c++ templates gcc c++11 variadic

c++ - GCC 4.8 está invirtiendo el paquete de parámetros de la plantilla variadic



templates c++11 (1)

Acabo de actualizar a GCC 4.8 y algunos códigos de plantilla variados ya no se compilan correctamente. He creado un ejemplo mínimo a continuación:

#include <tuple> #include <iostream> template <class T, class ... OtherT> void something( std::tuple<T, OtherT...> & tup ) { std::cout << std::get<1>(tup) << std::endl; } int main() { std::tuple<int, char, bool> myTuple(3, ''a'', true); // Compiles OK in GCC 4.6.3 but NOT 4.8 something<int, char, bool>( myTuple ); // Compiles OK in GCC 4.8 but NOT 4.6.3 something<int, bool, char>( myTuple ); return 0; }

El resultado de esto será (si se comenta la versión incorrecta para GCC 4.6.3 / 4.8) ''a''.

El error producido por GCC 4.6.3 es:

./test.cpp: In function ‘int main()’: ./test.cpp:18:39: error: no matching function for call to ‘something(std::tuple<int, char, bool>&)’ ./test.cpp:18:39: note: candidate is: ./test.cpp:5:6: note: template<class T, class ... OtherT> void something(std::tuple<_Head, _Tail ...>&)

El error producido por GCC 4.8 es:

./test.cpp: In function ‘int main()’: ./test.cpp:15:39: error: no matching function for call to ‘something(std::tuple<int, char, bool>&)’ something<int, char, bool>( myTuple ); ^ ./test.cpp:15:39: note: candidate is: ./test.cpp:5:6: note: template<class T, class ... OtherT> void something(std::tuple<_El0, _El ...>&) void something( std::tuple<T, OtherT...> & tup ) ^ ./test.cpp:5:6: note: template argument deduction/substitution failed: ./test.cpp:15:39: note: mismatched types ‘bool’ and ‘char’ something<int, char, bool>( myTuple );

Parece que en GCC 4.8, los tipos de plantillas variadas se invierten cuando se expanden, aunque, por extraño que parezca, no se "invierten" realmente como lo demuestra la salida, será "a" independientemente del orden. Clang 3.3 está de acuerdo con la salida de GCC 4.6.3.

¿Es este un error en GCC 4.8 o algo más?

EDITAR: agregue un informe de error a GCC aquí: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56774


Esto me parece un error, GCC 4.8.0 y GCC 4.7.2 parecen estar afectados. Clang 3.2 y GCC 4.6.3 están de acuerdo en que la primera llamada a something es la correcta y realmente no veo cómo GCC 4.7.2+ puede considerar aceptable la segunda llamada.

Yo diría: Informar un error contra GCC.

Actualización: Agregué un ejemplo minimalista al informe de errores de GCC, solo para ayudarles y probar que es un error puro del compilador y no tiene nada que ver con std::tuple . Aquí está el código reducido:

template< typename... > struct X {}; template< typename T, typename... Ts > void f( X< T, Ts... >& ) {} int main() { X< int, bool, char > t; f< int, char, bool >(t); }

Actualización 2: ahora está arreglado para GCC 4.7.3, GCC 4.8.1 y GCC 4.9 - ¡felicitaciones al equipo de GCC por una solución increíblemente rápida!