2013-03-28 3 views
23

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で生成されたエラーは次のとおりです。拡張時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); 

それはそうです奇妙なことに、彼らは出力によって証明されるように「本当に」逆転することはありません - それは順序にかかわらず「a」になります。 Clang 3.3はGCC 4.6.3の出力に同意します。

GCC 4.8などのバグですか?

編集:ここではGCCにバグレポートを追加しました:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56774これは私にはバグのように見える

答えて

15

は、GCC 4.8.0とGCC 4.7.2が影響しているように見えます。 Clang 3.2とGCC 4.6.3は、somethingへの最初の呼び出しが正しいことに同意し、私はGCC 4.7.2 +が2番目の呼び出しを受け入れ可能と考える方法を本当に見逃しています。

私は言っています:GCCに対するバグを報告してください。


アップデート:私はちょうどそれらを助け、それが純粋なコンパイラのバグだとstd::tupleとは何の関係もないことを証明するために、GCCのバグレポートに最小限の例を追加しました。ここで縮小コードは次のとおりです。

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チームに賛辞をめちゃくちゃ速い修正のために!

関連する問題