The difference between std :: decay and std :: remove_reference

When metaprogramming templates in C ++, I often come across the following:

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

I know that I should use something like std::decay in the return type, but why not work std::remove_reference ? What is the difference here? What about std::remove_cvref ?

+5
source share
2 answers

Removing the link will leave const and volatile . If this is what you want, then that will be enough.

Removing cvref does most of what happens, but does not convert function types and array types to pointers.

decay converts the type in such a way that you could reasonably store a copy of it in an array or in a struct or return it or pass it to a function.

+4
source

Consider, for example,

 #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 will remove any cv-qualifer, remove_reference will not. It will simply separate the "reference" part of the type.

From reference :

Applies the value of lvalue-to-rvalue, array-to-pointer, and function-to-pointer implicit conversions of type T, removes the cv qualifiers, and defines the resulting type as the type of the typedef member.

Therefore, std::decay will do more type conversions than std::remove_reference .

There are also type modifiers for more nuanced applications that will only perform parts of the set of possible decay transformations, for example, remove_cv , remove_volatile or, in C ++ 20, remove_cvref .

+8
source

Source: https://habr.com/ru/post/1274156/


All Articles