c++ - debe std:: common_type use std:: decay?
c++11 conditional-operator (1)
Dados los tipos A,B , me preocupa la definición exacta de std::common_type<A,B> , sin tener en cuenta el caso variadic std::common_type<A...> para tipos arbitrarios A... Entonces deja
using T = decltype(true ? std::declval<A>() : std::declval<B>());
using C = std::common_type<A,B>;
Ahora, de acuerdo con una serie de fuentes, he encontrado las siguientes relaciones (omitiendo typename para brevedad):
cppreference.com :
C::type = std::decay<T>::typecplusplus.com :
C::type = TGCC 4.8.1
<type_traits>implementación:C::type = std::decay<T>::typesiTes válida, de lo contrarioCno contiene un miembro::type("SFINAE-friendly")<type_traits>Clang 3.3<type_traits>:C::type = std::remove_reference<T>::type
Considero que la versión de GCC "amigable con SFINAE" es un detalle menor, mientras que std::remove_reference y std::decay prácticamente solo difieren en los arreglos y funciones incorporados, más la calificación std::remove_reference , por lo que tampoco me preocupa mucho. Así que mi pregunta es
¿Debería ser decay<T>::type o solo T ? ¿Cuál es la razón para usar decay<T>::type ? ¿Se trata solo de representar el resultado A() + B() por ejemplo, para expresiones aritméticas?
Por ejemplo, experimentando un poco, he encontrado que en el caso de la definición "solo T ", tenemos
common_type<int&,int&> = int&
common_type<int&,long&> = long
es decir, una referencia lvalue se mantiene si los tipos son iguales . Esto refleja el hecho de que
int a, b;
(true ? a : b) = 0;
es válido, mientras
int a;
long b;
(true ? a : b) = 0;
no es. Esta semántica de "permitir la asignación si los tipos son iguales" es exactamente lo que necesito en una aplicación, y tiendo a creer que el tipo common_type y la decay deben ser dos pasos independientes. ¿Debo usar mis propias definiciones?
debe std :: common_type use std :: decay?
Sí, ver open-std.org/JTC1/SC22/WG21/docs/lwg-defects.html#2141 .
Versión corta (versión larga, ver enlace arriba):
declval<A>()devuelve unA&&common_typese especifica mediantedeclval, n3337:template <class T, class U> struct common_type<T, U> { typedef decltype(true ? declval<T>() : declval<U>()) type; };common_type<int, int>::typepor lo tanto produceint&&, lo cual es inesperadopropuesta de resolución es agregar la
decaytemplate <class T, class U> struct common_type<T, U> { typedef decay_t < decltype(true ? declval<T>() : declval<U>()) > type; };common_type<int, int>::typeahora produceint