部分模板专业化的g ++ Bug

voi*_*ter 14 c++ templates template-specialization c++11 template-aliases

我正在为g ++(版本4.8.1_1,Macports)和clang ++(版本3.3,Macports)编写一些TMP密码.虽然g ++拒绝使用UNBRIDLED FURY的以下代码清单,但是 clang ++会用优雅辉煌来编译它.

  • 哪个编译器在右边?(我强烈怀疑它是g ++,但我希望在提交错误报告之前得到其他人的一些保证.)
  • 您有任何简单或优雅的变通方法可供建议吗?(我需要使用模板别名,因此切换到结构,导致g ++接受代码,不是一个选项.)

这是代码清单,专为您而制作.

template <class... Ts>
struct sequence;

template <int T>
struct integer;

// This definition of `extents` causes g++ to issue a compile-time error.
template <int... Ts>
using extents = sequence<integer<Ts>...>;

// However, this definition works without any problems.
// template <int... Ts>
// struct extents;

template <int A, int B, class Current>
struct foo;

template <int A, int B, int... Ts>
struct foo<A, B, extents<Ts...>>
{
    using type = int;
};

template <int B, int... Ts>
struct foo<B, B, extents<Ts...>>
{
    using type = int;
};

int main()
{
    using t = foo<1, 1, extents<>>::type;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是g ++的输出:

er.cpp: In function 'int main()':
er.cpp:39:41: error: ambiguous class template instantiation for 'struct foo<1, 1, sequence<> >'
  using t = typename foo<1, 1, extents<>>::type;
                                         ^
er.cpp:26:8: error: candidates are: struct foo<A, B, sequence<integer<Ts>...> >
 struct foo<A, B, extents<Ts...>>
        ^
er.cpp:32:8: error:                 struct foo<B, B, sequence<integer<Ts>...> >
 struct foo<B, B, extents<Ts...>>
        ^
er.cpp:39:43: error: 'type' in 'struct foo<1, 1, sequence<> >' does not name a type
  using t = typename foo<1, 1, extents<>>::type;
                                           ^
Run Code Online (Sandbox Code Playgroud)

这是clang ++的输出:

谢谢你的帮助!

Tem*_*Rex 8

这看起来像一个g ++错误,因为它显然foo<B, B, extents>更专业foo<A, B, extents>(后者可以匹配前者匹配的任何东西,但反之亦然),因此编译器应该选择专门化.

正如您所指出的那样,extents从模板别名更改为类模板可以解决问题.