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++: ??