¿Qué es std :: decay y cuándo debería usarse?

¿Cuáles son las razones de la existencia de std::decay ? ¿En qué situaciones es std::decay útil?

Obviamente se usa para descomponer los tipos std::atomic radiactivos en los no radioactivos.

N2609 es el documento que propuso std::decay . El documento explica:

En pocas palabras, decay::type es la transformación de tipo de identidad, excepto si T es un tipo de matriz o una referencia a un tipo de función. En esos casos, el tipo decay::type produce un puntero o un puntero a una función, respectivamente.

El ejemplo motivador es C ++ 03 std::make_pair :

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

que aceptó sus parámetros por valor para hacer que los literales de cadena funcionen:

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

Si acepta sus parámetros por referencia, entonces T1 se deducirá como un tipo de matriz, y luego construir un pair estará mal formado.

Pero obviamente esto conduce a ineficiencias significativas. De ahí la necesidad de decay , para aplicar el conjunto de transformaciones que ocurre cuando ocurre el valor de paso por paso, lo que le permite obtener la eficiencia de tomar los parámetros por referencia, pero aún obtener las transformaciones de tipo necesarias para que su código funcione con literales de cadenas , tipos de arreglos, tipos de funciones y similares:

 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)); } 

Nota: esta no es la implementación real make_pair C ++ 11: el make_pair C ++ 11 también desenvuelve std::reference_wrapper s.

Al tratar con funciones de plantilla que toman parámetros de un tipo de plantilla, a menudo tiene parámetros universales. Los parámetros universales son casi siempre referencias de un tipo u otro. También son const-volátiles calificados. Como tal, la mayoría de los rasgos de tipo no funcionan en ellos como era de esperar:

 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

La solución aquí es usar 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

    Intereting Posts