在 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
?
考虑例如
#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 限定符,remove_reference
不会。它只会剥离类型的“参考”部分。
从参考:
对类型 T 应用左值到右值、数组到指针和函数到指针的隐式转换,删除 cv 限定符,并将结果类型定义为成员 typedef 类型。
因此std::decay
将执行比std::remove_reference
.
还有更多类型修饰符用于更细微的应用程序,这些应用程序将仅执行一组可能的转换的选定部分decay
,例如remove_cv
,remove_volatile
或 C++20 中的remove_cvref
.
删除参考将离开const
and volatile
。如果这就是你想要的,那么它就足够了。
删除 cvref 完成了衰减的大部分工作,但不会将函数类型和数组类型转换为指针。
衰减以一种您可以合理地将其副本存储在数组或 a 中的方式转换类型struct
,或者将其从函数中返回或传递给函数。