gcc段错误编译嵌套参数包代码

tin*_*lyx 5 c++ c++11

我试图编写一个代码(截至2014年1月使用mingw32 gcc4.8.1),涉及两个参数包Args1...Args2....我在这里学到了(http://en.cppreference.com/w/cpp/language/parameter_pack)我需要一个嵌套类.Args1...Args2...相同长度(,最终我希望能推断Args2...Args1...).有时它们甚至可以是同一类型.所以我想using为这个简单的案例写一个简写语句作为开头:

template <typename R, typename ...Args>
using zip_t = zip<R, Args...>::with<Args...>;
Run Code Online (Sandbox Code Playgroud)

但是,gcc在编译此语句时会生成段错误.任何人都可以解释我是否做错了什么或这是一个gcc bug?

g++ -std=c++11 -I..  testUsing.cpp
testUsing.cpp: In substitution of 'template<class R, class ... Args> using zip_t = zip<R, Args1 ...>::with<Args ...> [with R = A; Args = {}]':
testUsing.cpp:19:15:   required from here
testUsing.cpp:16:45: internal compiler error: Segmentation fault
 using zip_t = zip<R, Args...>::with<Args...>;
                                             ^
Run Code Online (Sandbox Code Playgroud)

最小代码如下:(改编自http://en.cppreference.com/w/cpp/language/parameter_pack)

template<typename...> struct Tuple {};
template<typename T1, typename T2> struct Pair {};

template<class R,class ...Args1>  struct zip {
    template<class ...Args2> struct with {
        R flag;
        typedef Tuple<Pair<Args1, Args2>...> type;
        //Pair<Args1, Args2>... is the pack expansion, Pair<Args1, Args2> is the pattern
    };
};

typedef zip<bool,short, int>::with<unsigned short, unsigned>::type T1;
T1 make_zip1(bool) {return T1();}

template <typename R, typename ...Args>
using zip_t = zip<R, Args...>::with<Args...>;

template<typename A>
static zip_t<A>::type make_zip(A) {
  return zip_t<A>::type{};
}


//test code
int main() { return 0; }
Run Code Online (Sandbox Code Playgroud)

use*_*498 1

这肯定是一个 g++ bug。但你的代码不正确。

template <typename R, typename ...Args>
//using zip_t = zip<R, Args...>::with<Args...>;
using zip_t = typename zip<R, Args...>::template with<Args...>;
Run Code Online (Sandbox Code Playgroud)

问题是,您错过了两个关键字、一个类型名称和一个模板。

如果您添加了模板或类型名但错过了另一个,则 gcc 将不会出现核心段错误。Clang 会比 gcc 更好,它会告诉你错过了 typename 关键字或 template 关键字。

然而,如果你错过了这两个,gcc 会出现 seg 错误,而 clang 会告诉你一个错误,指出你错过了 typename,但它不会告诉你你错过了 template。