在下面的示例中, Abstract 是一个类模板,其第一个参数是一个类型,第二个参数是另一个模板,它带有一个bool以及任意数量的args .

template<bool,typename>
struct Default;

template< typename T = void,
          template<bool,typename ...> class = Default>
struct Abstract;

template<typename T>
struct Abstract<T>
{};

template<typename T, template<bool> class C>
struct Abstract<T,C> : Abstract<T>
{};

int main()
{}

Clang和C的输出如下:

Clang: http://rextester.com/BJSW46677

错误:类模板部分特化没有专门化任何模板参数;

G++ http://rextester.com/MDN65674

好的

所以,我决定对clang友好,并在 Abstract 的声明中添加了第三个参数 .

template< typename T = void,
          template<bool,typename ...> class = Default,
          typename = void >
struct Abstract;

现在,Clang和G都很好 . 我想Clang抱怨的原因是因为专业化没有真正专门化 . 但事实并非如此 . 它专门针对参数的数量 .

接下来,我为模板模板参数添加了另一个专门化 . 示例如下所示:

template<bool,typename>
struct Default;

template< typename T = void,
          template<bool,typename ...> class = Default,
          typename = void >
struct Abstract;

template<typename T>
struct Abstract<T>
{};

template<typename T, template<bool> class C>
struct Abstract<T,C> : Abstract<T>
{};

template<typename T, template<bool,typename> class G>
struct Abstract<T,G> : Abstract<T>
{};

int main()
{}

Clang和C的输出如下:

Clang: http://rextester.com/LJIOC38789

错误:重新定义Abstract <type-parameter-0-0,C,void>注意:先前的定义是struct Abstract <T,C>:Abstract <T>

G++: http://rextester.com/TSDRZ44717

确定 - (也不需要声明中的第三个参数)

我不认为Clang就在这里,因为第三个特化对模板模板参数有效,并且variadic模板参数允许我专门处理任意数量的参数 . 但是,我不确定 .

Question: 哪个编译器是错误的?为什么?从规范中获得一个引用并且对该主题更加清晰是非常好的 .