Подтвердить что ты не робот

GCC 4.8 реверсирует пакет параметров вариационного шаблона

Я только что обновился до GCC 4.8, и некоторый код вариационного шаблона больше не компилируется правильно. Я создал минимальный пример ниже:

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

Результат этого будет (если комментировать неправильную версию для GCC 4.6.3/4.8) 'А'.

Ошибка, созданная GCC 4.6.3:

./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 ...>&)

Ошибка, созданная GCC 4.8:

./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 );

Похоже, что в GCC 4.8 вариационные типы шаблонов меняются вспять при расширении, хотя, как ни странно, они не "действительно" обращаются вспять, как доказано выходом - это будет "а", независимо от порядка. Clang 3.3 согласуется с выходом GCC 4.6.3.

Является ли это ошибкой в ​​GCC 4.8 или что-то еще?

EDIT: добавлен отчет об ошибке в GCC: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56774

4b9b3361

Ответ 1

Это выглядит как ошибка для меня, GCC 4.8.0 и GCC 4.7.2 кажутся затронутыми. Clang 3.2 и GCC 4.6.3 согласны с тем, что первый вызов something является правильным, и я действительно не понимаю, как GCC 4.7.2+ может считать второй вызов приемлемым.

Я бы сказал: сообщите об ошибке против GCC.


Обновление: Я добавил минималистический пример в сообщение об ошибке GCC, чтобы помочь им и доказать, что это чистая ошибка компилятора и не имеет ничего общего с std::tuple. Здесь приведенный код:

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

Обновление 2: Теперь оно исправлено для GCC 4.7.3, GCC 4.8.1 и GCC 4.9 - высоко в команде GCC для безумно быстрого исправления!