什么是std::衰变和什么时候应该使用?

时间:2022-09-10 23:48:05

What are the reasons for the existence of std::decay? In what situations is std::decay useful?

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

2 个解决方案

#1


120  

<joke>It's obviously used to decay radioactive std::atomic types into non-radioactive ones.</joke>

很明显,它是用来衰变放射性的std::原子类型为非放射性的。。

N2609 is the paper that proposed std::decay. The paper explains:

N2609是提出std::衰变的论文。本文解释道:

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.

简单地说,衰变 ::类型是标识类型转换,除非T是数组类型或函数类型的引用。在这些情况下,衰变 ::类型分别生成一个指针或一个指向函数的指针。

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将被推断为一个数组类型,然后构造一对 将是不正确的。 ,>

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_wrappers.

注意:这并不是实际的c++ 11 make_pair实现——c++ 11 make_pair也不包装std::reference_wrappers。

#2


43  

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::衰变:

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

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

#1


120  

<joke>It's obviously used to decay radioactive std::atomic types into non-radioactive ones.</joke>

很明显,它是用来衰变放射性的std::原子类型为非放射性的。。

N2609 is the paper that proposed std::decay. The paper explains:

N2609是提出std::衰变的论文。本文解释道:

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.

简单地说,衰变 ::类型是标识类型转换,除非T是数组类型或函数类型的引用。在这些情况下,衰变 ::类型分别生成一个指针或一个指向函数的指针。

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将被推断为一个数组类型,然后构造一对 将是不正确的。 ,>

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_wrappers.

注意:这并不是实际的c++ 11 make_pair实现——c++ 11 make_pair也不包装std::reference_wrappers。

#2


43  

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::衰变:

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

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