std::decay
存在的原因是什么?
在什么情况下std::decay
有用?
答案 0 :(得分:154)
<笑话>它显然用于将放射性std::atomic
类型衰变为非放射性类型。< / joke>
N2609是提出std::decay
的论文。该文件解释说:
简单地说,
decay<T>::type
是身份类型转换,除了 如果T是数组类型或对函数类型的引用。在那些decay<T>::type
产生指针或指向函数的指针的情况, 分别
激励性的例子是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);
}
通过值接受其参数以使字符串文字起作用:
std::pair<std::string, int> p = make_pair("foo", 0);
如果它通过引用接受了它的参数,那么T1
将被推断为数组类型,然后构造pair<T1, T2>
将是不正确的。
但显然这会导致严重的低效率。因此需要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));
}
注意:这不是实际的C ++ 11 make_pair
实现 - C ++ 11 make_pair
也会展开std::reference_wrapper
。
答案 1 :(得分:49)
在处理带有模板类型参数的模板函数时,通常会有通用参数。通用参数几乎总是一种或另一种参考。他们也是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
此处的解决方案是使用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";
}