最終更新日時: 2025年07月09日 00時33分39秒 (JST)
Akira Takahashi が更新

履歴 編集

class template
<type_traits>

# std::unwrap_ref_decay(C++20)

    namespace std {
      template <class T>
      struct unwrap_ref_decay : unwrap_reference<decay_t<T>> {};

      template <class T>
      using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type;
    }

## 概要

`reference_wrapper<T>`型を`T&`型に展開し、型推論規則による型変換を行う。

この変換型特性は、関数で受け取ったパラメータをメンバ変数にもつオブジェクトを構築して返すような状況で頻出する型変換を行う。

例として、標準ライブラリ内では`std::make_pair()`や`std::make_tuple()`の戻り値型を求める際に使用する。

## 効果

- テンプレートパラメータ`T`を、`unwrap_reference`によって`reference_wrapper<T>`型を展開`T&`に展開し、`decay`によって型推論規則による型変換を行う。

## 例

    #include <cassert>
    #include <functional>
    #include <type_traits>

    template <class T>
    struct X {
      T t;
    };

    template <class T>
    X<std::unwrap_ref_decay_t<T>> f(T t)
    {
      return X<std::unwrap_ref_decay_t<T>>{t};
    }

    int main()
    {
      static_assert(std::is_same_v<
        std::unwrap_ref_decay_t<std::reference_wrapper<int>>,
        int&
      >);

      static_assert(std::is_same_v<
        std::unwrap_ref_decay_t<int[3]>,
        int*
      >);

      static_assert(std::is_same_v<
        std::unwrap_ref_decay_t<const char(&)[3]>,
        const char*
      >);

      static_assert(std::is_same_v<
        std::unwrap_ref_decay_t<int>,
        int
      >);

      static_assert(std::is_same_v<
        std::unwrap_ref_decay_t<const int&>,
        int
      >);

      // Xクラスに参照を保持させたい場合にstd::ref()を通して渡し、
      // そうでなければ単に引数を転送する。
      int a = 3;
      X x = f(std::ref(a));
      x.t = 2;
      assert(a == 2);

      int b = 4;
      X y = f(b);
      y.t = 5;
      assert(y.t == 5);
      assert(b == 4);

      // Xクラスに文字列リテラルを保持させたい場合に、
      // const char(&)[N]がconst char*に変換して保持させられる。
      X z = f("Hello");
      static_assert(std::is_same_v<decltype(z.t), const char*>);
    }

### 出力

## バージョン

### 言語

- C++20

### 処理系

- Clang: 8.0 ✅
- GCC: 9.1 ✅
- Visual C++: ??

## 参照

- P0318R1 `unwrap_ref_decay` and `unwrap_reference`
- LWG Issue 3348. `__cpp_lib_unwrap_ref` in wrong header