Что такое std :: decay и когда он должен использоваться?

Каковы причины существования std::decay ? В каких ситуациях полезно использовать std::decay ?

Он, очевидно, используется для разложения радиоактивных std::atomic типов на нерадиоактивные.

N2609 – это статья, в которой предлагается std::decay . В документе объясняется:

Проще говоря, decay::type – это преобразование типа идентичности, за исключением случаев, когда T является типом массива или ссылкой на тип функции. В этих случаях decay::type дает указатель или указатель на функцию, соответственно.

Мотивирующим примером является C ++ 03 std::make_pair :

 template  inline pair make_pair(T1 x, T2 y) { return pair(x, y); } 

который принял свои параметры по значению, чтобы заставить строковые литералы работать:

 std::pair p = make_pair("foo", 0); 

Если он принимает свои параметры по ссылке, то T1 будет выводиться как тип массива, а затем построение pair будет плохо сформировано.

Но, очевидно, это приводит к значительной неэффективности. Следовательно, необходимость в decay , применять набор преобразований, возникающих при переходе по значению, что позволяет вам эффективно использовать параметры по ссылке, но при этом получать преобразования типов, необходимые для работы вашего кода со строковыми литералами , типы массивов, типы функций и т.п.:

 template  inline pair< typename decay::type, typename decay::type > make_pair(T1&& x, T2&& y) { return pair< typename decay::type, typename decay::type >(std::forward(x), std::forward(y)); } 

Примечание: это не реальная реализация C ++ 11 make_pair – C ++ 11 make_pair также распаковывает std::reference_wrapper s.

При работе с функциями шаблона, которые принимают параметры типа шаблона, у вас часто есть универсальные параметры. Универсальные параметры почти всегда являются ссылками того или иного типа. Они также обладают непреодолимой силой. Таким образом, большинство черт типа не работают на них, как вы ожидали:

 template void func(T&& param) { if (std::is_same::value) std::cout << "param is an int\n"; else std::cout << "param is not an int\n"; } int main() { int three = 3; func(three); //prints "param is not an int"!!!! } 

http://coliru.stacked-crooked.com/a/24476e60bd906bed

Решением здесь является использование std::decay :

 template void func(T&& param) { if (std::is_same::type,int>::value) std::cout << "param is an int\n"; else std::cout << "param is not an int\n"; } 

http://coliru.stacked-crooked.com/a/8cbd0119a28a18bd

Давайте будем гением компьютера.