c++ templates c++11

typeid c++



std:: common_type con referencias a type_info (1)

Estoy perplejo: al actualizar a GCC 6 (RC1), algunos códigos de plantillas que utilizan std::common_type que funcionaron antes fallaron. Lo intenté en Clang, y eso también falla ... ¡así que debo estar haciendo algo mal!

El código equivale a:

#include <type_traits> #include <typeinfo> using namespace std; // common_type of two const type_info& is ok (compiles ok) common_type<const type_info&, const type_info&>::type func1(); // common_type of three type_info& is bad...(fails to compile) common_type<const type_info&, const type_info&, const type_info&>::type func2(); // common_type of two const int& is ok common_type<const int&, const int&>::type func3(); // common_type of three const int& is ok too! common_type<const int&, const int&, const int&>::type func4();

El segundo common_type con tres parámetros de tipo std::type_info const & falla en compilar. clang cryptically sugiere que use un std::common_type dos argumentos, pero esto es en una expansión de plantilla donde no puedo controlar las entradas.

Esto parece muy extraño: ¿por qué const type_info& case con 3 pero ningún otro tipo de tipo aparentemente equivalente fallaría?

Consulte aquí: https://godbolt.org/g/Ob4y0x


Primero, common_type_t<T1, T2> es (aproximadamente) std::decay_t<decltype(true? std::declval<T1>() : std::declval<T2>())> . Disminuye el tipo: elimina la referencia, elimina la calificación CV de nivel superior y realiza la conversión de matriz a puntero y de función a puntero.

Entonces, common_type<const type_info&, const type_info&>::type es type_info . Si func1 la declaración de func1 parece funcionar, tendrá graves problemas al escribir su definición.

common_type_t<T1, T2, T3> es common_type_t<common_type_t<T1, T2>, T3> , por common_type<const type_info&, const type_info&, const type_info&>::type tanto common_type<const type_info&, const type_info&, const type_info&>::type is common_type<type_info, const type_info&>::type .

Esto da como resultado una expresión ternaria de categoría de valor mixto, que según las reglas en [expr.cond] intentará hacer que un type_info temporal salga del operando elegido, que no funciona porque se type_info el constructor de copia de type_info .

En implementaciones amigables con SFINAE, esto resulta en un tipo common_type<const type_info&, const type_info&, const type_info&> que no tiene ningún type miembro. Si utiliza una implementación no compatible con SFINAE, obtendrá un error difícil en su lugar.