什么是std :: decay,什么时候应该使用?

std::decay存在的原因是什么? std::decay在什么情况下有用?

<笑话>它显然是用来衰减放射性std::atomictypes为非放射性的</ joke>

N2609是提出std::decay的论文。 该文件解释说:

简单地说, decay<T>::type是标识types转换,除非T是数组types或对函数types的引用。 在这些情况下, 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); } 

它通过值接受它的参数使string文字工作:

 std::pair<std::string, int> p = make_pair("foo", 0); 

如果通过引用接受它的参数,则T1将被推导为一个数组types,然后构造一个pair<T1, T2>将是格式不正确的。

但显然这导致显着的低效率。 因此,需要decay ,应用传值时发生的一组转换,使您可以通过引用获得参数的效率,但仍然可以获得代码使用string文字所需的types转换,数组types,函数types等等:

 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

在处理模板types参数的模板函数时,您经常使用通用参数。 通用参数几乎总是参考一种或另一种。 他们也是常数不稳定的资格。 因此,大多数types特征并不像你所期望的那样工作:

 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

这里的解决scheme是使用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"; } 

http://coliru.stacked-crooked.com/a/8cbd0119a28a18bd