最終更新日時: 2025年06月11日 23時15分20秒 (JST)
Raclamusi が更新

履歴 編集

class template
<type_traits>

# std::unwrap_reference(C++20)

    namespace std {
      template <class T>
      struct unwrap_reference {
        using type = …;
      };

      template <class T>
      using unwrap_reference_t = typename unwrap_reference<T>::type;
    }

## 概要

`reference_wrapper<T>`型を`T&`型に展開する。

## 効果

- テンプレートパラメータ`T`が`reference_wrapper<T>`であれば、`T&`型をメンバ型`type`として定義する
- そうでなければ、テンプレートパラメータ`T`をメンバ型`type`として定義する

## 例

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

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

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

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

      static_assert(std::is_same_v<
        std::unwrap_reference<int>::type,
        int
      >);

      static_assert(std::is_same_v<
        std::unwrap_reference<const int&>::type,
        const 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);
    }

### 出力

## 実装例

    namespace std {
      template <class T>
      struct unwrap_reference { using type = T; };

      template <class T>
      struct unwrap_reference<reference_wrapper<T>> { using type = T&; };
    }

## バージョン

### 言語

- 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