std::unwrap_reference, std::unwrap_ref_decay
From cppreference.com
< cpp | utility | functional
C++
Feature test macros (C++20)
Concepts library (C++20)
Metaprogramming library (C++11)
Ranges library (C++20)
Filesystem library (C++17)
Concurrency support library (C++11)
Execution control library (C++26)
Utilities library
Relational operators (deprecated in C++20)
Integer comparison functions
Swap and type operations
Common vocabulary types
Type support (basic types, RTTI)
Library feature-test macros (C++20)
(C++11)
(C++20)
(C++26)
(C++20)
Coroutine support (C++20)
Contract support (C++26)
(C++20)(C++20)
(C++20)
(C++20)
(C++20)
(C++20)
(C++20)
(C++20)
(C++20)
(C++20)
(C++20)
(C++20)
(C++20)
(C++20)
(C++20)(C++20)(C++20)
(C++20)(C++20)(C++20)
General utilities
(C++20)(C++20)(C++20)
(C++20)(C++20)(C++20)
(C++20)
Function objects
Old binders and adaptors
(C++11)
(C++23)
(C++26)
(C++26)
(C++11)
(C++11)
(C++20)(C++23)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)(C++11)
unwrap_referenceunwrap_ref_decay
(C++20)(C++20)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++17)
(C++17)
(C++17)
(C++17)
(C++20)
(C++20)
(C++20)
(C++20)
(C++20)
(C++20)
(C++20)
(until C++17*)
(until C++17*)
(until C++17*)
(until C++17*)
(until C++17*)
(until C++17*)
(until C++17*)(until C++17*)(until C++17*)(until C++17*)
(until C++20*)
(until C++20*)
(until C++17*)(until C++17*)
(until C++17*)(until C++17*)
(until C++17*)
(until C++17*)(until C++17*)(until C++17*)(until C++17*)
(until C++20*)
(until C++20*)
Defined in header
<type_traits>
Defined in header
<functional>
template< class T >
struct unwrap_reference;
(1)
(since C++20)
struct unwrap_reference;
template< class T >
struct unwrap_ref_decay;
(2)
(since C++20)
struct unwrap_ref_decay;
Unwraps any std::reference_wrapper : changing std::reference_wrapper <U> to U&
.
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.
[edit] Nested types
Type
Definition
type
(1) U&
if T
is std::reference_wrapper <U>; T
otherwise
(2) U&
if std::decay_t <T> is std::reference_wrapper <U>; std::decay_t <T> otherwise
[edit] Helper types
template<class T>
using unwrap_reference_t = unwrap_reference<T>::type;
(1)
(since C++20)
using unwrap_reference_t = unwrap_reference<T>::type;
template<class T>
using unwrap_ref_decay_t = unwrap_ref_decay<T>::type;
(2)
(since C++20)
using unwrap_ref_decay_t = unwrap_ref_decay<T>::type;
[edit] Possible implementation
template<class T> struct unwrap_reference { using type = T; }; template<class U> struct unwrap_reference<std::reference_wrapper <U>> { using type = U&; }; template<class T> struct unwrap_ref_decay : std::unwrap_reference<std::decay_t <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
Run this code
#include <cassert> #include <functional> #include <iostream> #include <type_traits> int main() { static_assert(std::is_same_v <std::unwrap_reference_t<int>, int>); static_assert(std::is_same_v <std::unwrap_reference_t<const int>, 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 <int>; using X = std::unwrap_reference_t<T>; static_assert(std::is_same_v <X, int&>); } { using T = std::reference_wrapper <int&>; using X = std::unwrap_reference_t<T>; static_assert(std::is_same_v <X, int&>); } 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>); 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<T>; static_assert(std::is_same_v <X, int&>); } { auto reset = []<typename T>(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<U> decltype(auto) r = std::unwrap_reference_t<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:
r: 1 r: 2