gla*_*erl 16 c++ templates template-specialization variadic-templates c++11
我有代码:
#include <cstdio>
template<template<typename...> class>
struct Foo
{
enum { n = 77 };
};
template<template<typename, typename...> class C>
struct Foo<C>
{
enum { n = 99 };
};
template<typename...> struct A { };
template<typename, typename...> struct B { };
int main(int, char**)
{
printf("%d\n", Foo<A>::n);
printf("%d\n", Foo<B>::n);
}
Run Code Online (Sandbox Code Playgroud)
这个想法是它template<typename, typename...> class的一个子集template<typename...> class,因此有可能专注于它.但它非常深奥,所以也许不是.我们来试试吧.
GCC 4.7说:
$ g++ -std=c++11 test157.cpp
Run Code Online (Sandbox Code Playgroud)
它汇编了!
运行它:
$ ./a.out
77
99
Run Code Online (Sandbox Code Playgroud)
有用!
Clang 3.1说:
$ clang++ -std=c++11 test157.cpp
test157.cpp:10:8: error: class template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list
struct Foo<C>
^ ~~~
test157.cpp:9:10: error: too many template parameters in template template parameter redeclaration
template<template<typename, typename...> class C>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test157.cpp:3:10: note: previous template template parameter is here
template<template<typename...> class>
^~~~~~~~~~~~~~~~~~~~~
2 errors generated.
Run Code Online (Sandbox Code Playgroud)
谁是对的?
Clang拒绝部分专业化是错误的.要知道如何解释错误消息,您需要了解clang诊断的内容.它意味着诊断部分特化,其参数完全匹配主类模板(<param1, param2, ... , paramN>)的隐式参数列表.
但是参数列表不同,所以clang不会诊断它.特别是这与部分特化与或多或少的参数匹配无关.考虑
template<typename A, typename B> class C;
template<typename B, typename A> class C<A, B> {};
Run Code Online (Sandbox Code Playgroud)
这里的部分特化匹配所有内容,而不是主模板匹配的内容.并且两个模板的参数列表都不同,因此这种部分特化是有效的,就像你的一样.