table of contents
- Tumbleweed 2024.07.05-1.3
- Leap-16.0
- Leap-15.6
std::unwrap_reference,std::unwrap_ref_decay(3) | C++ Standard Libary | std::unwrap_reference,std::unwrap_ref_decay(3) |
NAME¶
std::unwrap_reference,std::unwrap_ref_decay - std::unwrap_reference,std::unwrap_ref_decay
Synopsis¶
Defined in header <type_traits>
Defined in header <functional>
template< class T > (1) (since C++20)
struct unwrap_reference;
template< class T > (2) (since C++20)
struct unwrap_ref_decay;
1) If T is std::reference_wrapper<U> for some type U, provides a member
type alias
type that names U&; otherwise, provides a member type alias type that
names T.
2) If T is std::reference_wrapper<U> for some type U, ignoring
cv-qualification and
referenceness, provides a member type alias type that names U&;
otherwise, provides
a member type alias type that names std::decay_t<T>.
If the program adds specializations for any of the templates described on
this page,
the behavior is undefined.
Member types¶
Name Definition
(1) U& if T is std::reference_wrapper<U>; T otherwise
type (2) U& if std::decay_t<T> is
std::reference_wrapper<U>; std::decay_t<T>
otherwise
Helper types¶
template<class T> (1) (since C++20)
using unwrap_reference_t = unwrap_reference<T>::type;
template<class T> (2) (since C++20)
using unwrap_ref_decay_t = unwrap_ref_decay<T>::type;
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>>
{};
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
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
See also¶
reference_wrapper CopyConstructible and CopyAssignable reference
wrapper
(C++11) (class template)
make_pair creates a pair object of type, defined by the argument types
(function template)
make_tuple creates a tuple object of the type defined by the argument types
(C++11) (function template)
2024.06.10 | http://cppreference.com |