Разница между std:: decay и std:: удалить ссылку
когда метапрограммирование шаблонов на 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
?
2 ответов
удаление ссылки оставит const
и volatile
. Если это то, чего вы хотите, то этого будет достаточно.
удаление cvref делает большую часть того, что делает decay, но не преобразует типы функций и типы массивов в указатели.
decay преобразует тип таким образом, что вы можете разумно хранить его копию в массиве или в struct
, или вернуть его или передать его в функцию.
рассмотрим, например,
#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
не будет. Он просто очистит "справочную" часть типа.
С ссылка:
применяет 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
.