<joke>It's obviously used to decay radioactive std::atomic
types into non-radioactive ones.</joke>
N2609 is the paper that proposed std::decay
. The paper explains:
Simply put, decay<T>::type
is the identity type-transformation except
if T is an array type or a reference to a function type. In those
cases the decay<T>::type
yields a pointer or a pointer to a function,
respectively.
The motivating example is C++03 std::make_pair
:
template <class T1, class T2>
inline pair<T1,T2> make_pair(T1 x, T2 y)
{
return pair<T1,T2>(x, y);
}
which accepted its parameters by value to make string literals work:
std::pair<std::string, int> p = make_pair("foo", 0);
If it accepted its parameters by reference, then T1
will be deduced as an array type, and then constructing a pair<T1, T2>
will be ill-formed.
But obviously this leads to significant inefficiencies. Hence the need for decay
, to apply the set of transformations that occurs when pass-by-value occurs, allowing you to get the efficiency of taking the parameters by reference, but still get the type transformations needed for your code to work with string literals, array types, function types and the like:
template <class T1, class T2>
inline pair< typename decay<T1>::type, typename decay<T2>::type >
make_pair(T1&& x, T2&& y)
{
return pair< typename decay<T1>::type,
typename decay<T2>::type >(std::forward<T1>(x),
std::forward<T2>(y));
}
Note: this is not the actual C++11 make_pair
implementation - the C++11 make_pair
also unwraps std::reference_wrapper
s.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…