23

我刚刚升级到 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 的不正确版本)'a'。

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 中,可变参数模板类型在扩展时被反转,但奇怪的是,它们并没有“真正”被反转,正如输出所证明的那样——无论排序如何,它都将是“a”。Clang 3.3 与 GCC 4.6.3 输出一致。

这是 GCC 4.8 中的错误还是其他错误?

编辑:在此处向 GCC 添加了错误报告:http: //gcc.gnu.org/bugzilla/show_bug.cgi?id= 56774

4

1 回答 1

15

这对我来说似乎是一个错误,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 团队的快速修复!

于 2013-03-28T21:11:54.597 回答