我有代码:
#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 …Run Code Online (Sandbox Code Playgroud) c++ templates template-specialization variadic-templates c++11
在下面的示例中,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()
{}
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
现在,Clang和G ++都很好.我想Clang抱怨的原因是因为专业化并没有真正专门化.但事实并非如此.它专门针对参数的数量.
接下来,我为模板模板参数添加了另一个专门化.示例如下所示:
template<bool,typename>
struct Default;
template< typename T = void,
template<bool,typename ...> class = …Run Code Online (Sandbox Code Playgroud) [temp.deduct.type]第8段列出了所有推导出的上下文,但它似乎没有包括where 类引用类模板并引用模板模板参数.这是推断的背景吗?template-name<TT>template-nameTT
如果是,为什么?
如果没有,请考虑以下代码:
template<template<typename> class U, template<typename> class V>
struct foo {};
template<template<typename> class U>
struct foo<U, U> {};
int main() {}
Run Code Online (Sandbox Code Playgroud)
此代码编译锵7.0.0下和GCC 8.0.1,这意味着编译器考虑部分特比主模板,这意味着更加专业化U和V在主模板被成功地推导出对foo<U, U>.这是编译器错误吗?