std::decay 和 std::remove_reference 之间的区别
Difference between std::decay and std::remove_reference
在 C++ 中进行模板元编程时,我经常 运行 变成如下内容:
template <typename T>
S<T> make_wrapper(T&& t) { return S<T>(std::forward<T>(t)); }
我知道我应该在 return 类型中使用类似 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-qualifer,remove_reference
不会。它只会去除类型的 "reference" 部分。
来自reference:
Applies lvalue-to-rvalue, array-to-pointer, and function-to-pointer
implicit conversions to the type T, removes cv-qualifiers, and defines
the resulting type as the member typedef type.
因此 std::decay
将执行比 std::remove_reference
更多的类型转换。
还有更多类型修饰符用于更细微的应用程序,这些应用程序将仅执行可能转换集中的选定部分 decay
,如 remove_cv
、remove_volatile
或在 C 中++20, remove_cvref
.
删除引用将留下 const
和 volatile
。如果那是你想要的,那就足够了。
删除 cvref 可以完成 decay 的大部分工作,但不会将函数类型和数组类型转换为指针。
decay 以一种方式转换类型,您可以合理地将其副本存储在数组或 struct
中,或者 return 从函数或将其传递给函数。
在 C++ 中进行模板元编程时,我经常 运行 变成如下内容:
template <typename T>
S<T> make_wrapper(T&& t) { return S<T>(std::forward<T>(t)); }
我知道我应该在 return 类型中使用类似 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-qualifer,remove_reference
不会。它只会去除类型的 "reference" 部分。
来自reference:
Applies lvalue-to-rvalue, array-to-pointer, and function-to-pointer implicit conversions to the type T, removes cv-qualifiers, and defines the resulting type as the member typedef type.
因此 std::decay
将执行比 std::remove_reference
更多的类型转换。
还有更多类型修饰符用于更细微的应用程序,这些应用程序将仅执行可能转换集中的选定部分 decay
,如 remove_cv
、remove_volatile
或在 C 中++20, remove_cvref
.
删除引用将留下 const
和 volatile
。如果那是你想要的,那就足够了。
删除 cvref 可以完成 decay 的大部分工作,但不会将函数类型和数组类型转换为指针。
decay 以一种方式转换类型,您可以合理地将其副本存储在数组或 struct
中,或者 return 从函数或将其传递给函数。