std::unwrap_reference, std::unwrap_ref_decay - cppreference.com (original) (raw)

Defined in header <type_traits>
Defined in header
template< class T > struct unwrap_reference; (1) (since C++20)
template< class T > struct unwrap_ref_decay; (2) (since C++20)

Unwraps any std::reference_wrapper: changing std::reference_wrapper<U> to U&.

  1. If T is a specialization of std::reference_wrapper, unwraps it; otherwise, T remains the same.

  2. If the decayed T is a specialization of std::reference_wrapper, unwraps it; otherwise, T is decayed.

If the program adds specializations for any of the templates described on this page, the behavior is undefined.

Contents

[edit] Nested types

[edit] Helper types

template<class T> using unwrap_reference_t = unwrap_reference<T>::type; (1) (since C++20)
template<class T> using unwrap_ref_decay_t = unwrap_ref_decay<T>::type; (2) (since C++20)

[edit] Possible implementation

template struct unwrap_reference { using type = T; }; template struct unwrap_reference<std::reference_wrapper> { using type = U&; };   template struct unwrap_ref_decay : std::unwrap_reference<std::decay_t> {};

[edit] Notes

std::unwrap_ref_decay performs the same transformation as used by std::make_pair and std::make_tuple.

Feature-test macro Value Std Feature
__cpp_lib_unwrap_ref 201811L (C++20) std::unwrap_ref_decay and std::unwrap_reference

[edit] Example

#include #include #include #include   int main() { static_assert(std::is_same_v<std::unwrap_reference_t, int>); static_assert(std::is_same_v<std::unwrap_reference_t, const int>); static_assert(std::is_same_v<std::unwrap_reference_t<int&>, int&>); static_assert(std::is_same_v<std::unwrap_reference_t<int&&>, int&&>); static_assert(std::is_same_v<std::unwrap_reference_t<int*>, int*>);   { using T = std::reference_wrapper; using X = std::unwrap_reference_t; static_assert(std::is_same_v<X, int&>); } { using T = std::reference_wrapper<int&>; using X = std::unwrap_reference_t; static_assert(std::is_same_v<X, int&>); }   static_assert(std::is_same_v<std::unwrap_ref_decay_t, int>); static_assert(std::is_same_v<std::unwrap_ref_decay_t, int>); static_assert(std::is_same_v<std::unwrap_ref_decay_t<const int&>, int>);   { using T = std::reference_wrapper<int&&>; using X = std::unwrap_ref_decay_t; static_assert(std::is_same_v<X, int&>); }   { auto reset = [](T&& z) { // x = 0; // Error: does not work if T is reference_wrapper<> // converts T&& into T& for ordinary types // converts T&& into U& for reference_wrapper decltype(auto) r = std::unwrap_reference_t(z); std::cout << "r: " << r << '\n'; r = 0; // OK, r has reference type };   int x = 1; reset(x); assert(x == 0);   int y = 2; reset(std::ref(y)); assert(y == 0); } }

Output:

[edit] See also