T.C*_*.C. 165

<笑话>它显然用于将放射性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); 
}
Run Code Online (Sandbox Code Playgroud)

它按值接受其参数以使字符串文字起作用:

std::pair<std::string, int> p = make_pair("foo", 0);
Run Code Online (Sandbox Code Playgroud)

如果它通过引用接受它的参数,那么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)); 
}
Run Code Online (Sandbox Code Playgroud)

注意:这不是实际的C++ 11 make_pair实现 - C++ 11 make_pair也可以解包std::reference_wrapper.

  • 我明白了,通过这种方式,我们将得到pair <char [4],int>,它只接受4个字符的字符串 (5认同)
  • @Zebrafish这是数组衰减。例如:template &lt;typename T&gt; void f(T&); f(“ abc”); T是char(&)[4],但是template &lt;typename T&gt; void f(T); f(“ abc”); T是char *; 您还可以在此处找到说明:/sf/ask/545848761/ (3认同)
  • “T1 将被推导为数组类型,然后构造 pair&lt;T1, T2&gt; 将是格式错误的。” 这里有什么问题? (2认同)

Moo*_*uck 59

处理带有模板类型参数的模板函数时,通常会有通用参数.通用参数几乎总是一种或另一种参考.他们也是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"!!!!
}
Run Code Online (Sandbox Code Playgroud)

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";
}
Run Code Online (Sandbox Code Playgroud)

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

  • 我对此并不满意.`decay`是非常激进的,例如,如果应用于对数组的引用,它会产生一个指针.对于这种元编程恕我直言,它通常过于激进. (13认同)
  • @SergeRogatch在"通用参数"/通用引用/转发引用的情况下,我只是`remove_const_t <remove_reference_t <T>>`,可能包含在自定义元函数中. (4认同)
  • @GabrielStaples 是的。根据模板,`int`、`const int`、`int&amp;`、`const int&amp;`、`int&amp;&amp;`、`const int&amp;&amp;`、`volatile int`、`volatile int&amp;`、`volatile int&amp;&amp;`等都是不同的。 (4认同)
  • @savram:在这些代码中:不是。我们只检查类型,而不是值。如果我们删除参数的名称,一切都应该正常工作。 (2认同)