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_cvremove_volatile 或在 C 中++20, remove_cvref.

删除引用将留下 constvolatile。如果那是你想要的,那就足够了。

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

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