2013-03-28 9 views
23

Właśnie zaktualizowałem GCC 4.8 i niektóre szablony szablonów variadic nie są już poprawnie kompilowane. Utworzyłem minimalny przykład poniżej:GCC 4.8 odwraca pakiet parametrów szablonu variadic

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

Wyjście to będzie (jeśli zakomentowanie nieprawidłową wersję dla GCC 4.6.3/4.8) „A”.

Błąd produkowane przez GCC 4.6.3 jest:

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

Błąd produkowane przez 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); 

Wydaje się, że w GCC 4.8, o zmiennej liczbie argumentów rodzaje szablonów są odwrócone po rozwinięciu , ale co dziwne, nie "naprawdę" zostają odwrócone, co udowodnił wynik - będzie to "a" niezależnie od kolejności. Clang 3.3 zgadza się z danymi wyjściowymi GCC 4.6.3.

Czy to błąd w GCC 4.8 lub coś innego?

EDIT: dodaje raport o błędzie do GCC tutaj: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56774

Odpowiedz

15

To wygląda jak błąd do mnie, GCC 4.8.0 i 4.7.2 GCC wydaje się być ograniczona. Clang 3.2 i GCC 4.6.3 zgadzają się, że pierwsze połączenie z something jest poprawne i naprawdę nie widzę, jak GCC 4.7.2+ może uznać drugie zaproszenie za akceptowalne.

Powiedziałbym: Zgłoś błąd przeciwko GCC.


Aktualizacja: dodałem minimalistyczny przykład do raportu o błędzie GCC, żeby im pomóc i udowodnić, że jest to czysta kompilator błąd i nie ma nic wspólnego z std::tuple. Oto zredukowany kod:

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

Aktualizacja 2: To już ustalona dla GCC 4.7.3, GCC 4.8.1 i GCC 4.9 - Uznanie dla zespołu GCC dla szalenie szybko naprawić!

Powiązane problemy