- functional[meta header]
- std[meta namespace]
- class template[meta id-type]
- cpp20[meta cpp]
namespace std {
template <class T>
struct unwrap_reference;
}
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);
}
- std::unwrap_reference[color ff0000]
- std::reference_wrapper[link ref.md]
- std::ref[link ref.md]
namespace std {
template <class T>
struct unwrap_reference { using type = T; }
template <class T>
struct unwrap_reference<reference_wrapper<T>> { using type = T&; }
}
- reference_wrapper[link reference_wrapper.md]
- C++20
- Clang: 8.0
- GCC: 9.1
- Visual C++: ??