在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
呢?
答案 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_cv
,remove_volatile
或在C ++中20,remove_cvref
。
答案 1 :(得分:7)
删除引用会离开const
和volatile
。如果那就是你想要的,那就足够了。
删除cvref可以完成大部分衰减,但不会将函数类型和数组类型转换为指针。
decay以一种方式转换类型,您可以合理地将其副本存储在数组或struct
中,或者将其从函数中返回或传递给函数。