¿Cuáles son las razones de la existencia de std::decay? ¿En qué situaciones es std::decayútil?
                    
                        c++
                                c++11
                                standard-library
                                
                    
                    
                        Eric Javier Hernández Saura
fuente
                
                fuente

decay_t<decltype(...)>es una buena combinación, para ver quéautodeduciría.Respuestas:
<joke> Obviamente se usa para descomponer los
std::atomictipos radiactivos en no radiactivos. </joke>N2609 es el documento que propuso
std::decay. El artículo explica:El ejemplo motivador es C ++ 03
std::make_pair:que aceptó sus parámetros por valor para hacer que los literales de cadena funcionen:
Si aceptó sus parámetros por referencia,
T1se deducirá como un tipo de matriz, y luego la construcción de unpair<T1, T2>estará mal formada.Pero obviamente esto conduce a ineficiencias significativas. De ahí la necesidad de
decayaplicar el conjunto de transformaciones que ocurre cuando ocurre el paso por valor, 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 cadena, tipos de matriz, tipos de funciones y similares:Nota: esta no es la
make_pairimplementación real de C ++ 11 : el C ++ 11make_pairtambién desenvuelvestd::reference_wrappers.fuente
Cuando se trata de 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 están calificados con volatilidad constante. Como tal, la mayoría de los rasgos tipográficos no funcionan en ellos como cabría esperar:
http://coliru.stacked-crooked.com/a/24476e60bd906bed
La solución aquí es usar
std::decay:http://coliru.stacked-crooked.com/a/8cbd0119a28a18bd
fuente
decayes muy agresivo, por ejemplo, si se aplica a una referencia a una matriz, produce un puntero. Por lo general, es demasiado agresivo para este tipo de metaprogramación en mi humilde opinión.remove_const_t< remove_reference_t<T> >, posiblemente, envuelto en una metafunción personalizada.