C++ 什么是 std::decay 以及何时使用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25732386/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is std::decay and when it should be used?
提问by Eric Javier Hernandez Saura
What are the reasons for the existence of std::decay
?
In what situations is std::decay
useful?
存在的原因是std::decay
什么?在什么情况下std::decay
有用?
回答by T.C.
<joke>It's obviously used to decay radioactive std::atomic
types into non-radioactive ones.</joke>
<joke>它显然用于将放射性std::atomic
类型衰变成非放射性类型。</joke>
N2609is the paper that proposed std::decay
. The paper explains:
N2609是提出的论文std::decay
。论文解释说:
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 thedecay<T>::type
yields a pointer or a pointer to a function, respectively.
简单地说,
decay<T>::type
就是身份类型转换,除非 T 是数组类型或对函数类型的引用。在这些情况下,分别decay<T>::type
产生一个指针或指向函数的指针。
The motivating example is C++03 std::make_pair
:
激励示例是 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.
如果它通过引用接受其参数,T1
则将被推导为数组类型,然后构造 apair<T1, T2>
将是格式错误的。
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:
但显然这会导致显着的低效率。因此需要decay
, 应用发生传值时发生的一组转换,允许您获得通过引用获取参数的效率,但仍然可以获得代码处理字符串文字所需的类型转换,数组类型、函数类型等:
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.
注意:这不是实际的 C++11make_pair
实现 - C++11make_pair
也解包std::reference_wrapper
s。
回答by Mooing Duck
When dealing with template functions that take parameters of a template type, you often have universal parameters. Universal parameters are almost always references of one sort or another. They're also const-volatile qualified. As such, most type traits don't work on them as you'd expect:
在处理采用模板类型参数的模板函数时,您通常会使用通用参数。通用参数几乎总是一种或另一种引用。它们也是 const-volatile 合格的。因此,大多数类型特征并不像您期望的那样对它们起作用:
template<class T>
void func(T&& param) {
if (std::is_same<T,int>::value)
std::cout << "param is an int\n";
else
std::cout << "param is not an int\n";
}
int main() {
int three = 3;
func(three); //prints "param is not an int"!!!!
}
http://coliru.stacked-crooked.com/a/24476e60bd906bed
http://coliru.stacked-crooked.com/a/24476e60bd906bed
The solution here is to use std::decay
:
这里的解决方案是使用std::decay
:
template<class T>
void func(T&& param) {
if (std::is_same<typename std::decay<T>::type,int>::value)
std::cout << "param is an int\n";
else
std::cout << "param is not an int\n";
}