std :: decay和std :: remove_reference

时间:2017-12-18 15:36:16

标签: c++ c++11 templates c++20

在C ++中进行模板元编程时,我经常碰到以下内容:

template <typename T>
S<T> make_wrapper(T&& t) { return S<T>(std::forward<T>(t)); }

我知道我应该在返回类型中使用类似std::decay的内容,但为什么std::remove_reference也不能正常工作?这有什么区别?那么std::remove_cvref呢?

2 个答案:

答案 0 :(得分:11)

考虑例如

#include <type_traits>

int main()
{
    static_assert(std::is_same_v<
        std::decay_t<const int&>, 
        std::remove_reference_t<const int&>
    >); // int != const int
}

std::decay会删除所有cv-qualifer,remove_reference不会。它只会删除该类型的“引用”部分。

来自reference

  

应用lvalue-to-rvalue,array-to-pointer和function-to-pointer   隐式转换为类型T,删除cv限定符和定义   结果类型为成员typedef类型。

因此,std::decay将执行比std::remove_reference更多的类型转化。

对于更细微的应用程序还有其他类型修饰符,它们只执行decay可能转换集的选定部分,如remove_cvremove_volatile或在C ++中20,remove_cvref

答案 1 :(得分:7)

删除引用会离开constvolatile。如果那就是你想要的,那就足够了。

删除cvref可以完成大部分衰减,但不会将函数类型和数组类型转换为指针。

decay以一种方式转换类型,您可以合理地将其副本存储在数组或struct中,或者将其从函数中返回或传递给函数。