我不明白应该如何使用以下功能.当我调用A :: f时我可以省略模板参数,但我不明白为什么.
- template <typename... Args>
- struct A
- {
- template <Args...>
- void f() {}
- };
- int main()
- {
- A<int,bool> a;
- a.f();
- }
解决方法
template< typename ... Args>是一个可变参数模板.这意味着,您可以指定任意数量的模板类型参数,但我想您已经知道了.
每当Args …出现在模板代码中时,它将被解压缩(“扩展”)到实例化的类型.在您的示例中,这是int,bool.因此,当完全展开时,您的类将变为以下定义:
- struct A<int,bool>
- {
- template <int,bool>
- void f() {}
- };
这意味着,A< int,bool> :: f()再次被模板化(参数被解压缩到另一个模板声明中,就像你所说的那样),但这次使用非类型模板参数,类型为int和bool(它们’匿名),所以你可以像这样实例化f():
- a.f<1,true>();
不幸的是,g似乎有一个bug和won’t accept这段代码,而它是accepts你的代码.
clang接受这两个代码.我希望在你的代码中,clang不关心int和bool模板参数是否被省略,但是当它们被指定时它不会抱怨(与g相反).
用法示例:
如果要使用指定的值,则它们不能是匿名的(显然).例如,您可以在f()中提供一个格式字符串,用于“printf”模板值,如下所示:
- template <Args ...values>
- void f(const char *fmt) {
- std::printf(fmt,values...);
- }
然后,以下代码
- A<int> a;
- a.f<42>("The answer is %d!\n");
将打印:
- The answer is 42!
但是,使用上面的语法(Args …扩展为匿名非类型模板参数),模板参数基本上是无用的.
没有指定值,它仍然编译(这让我感到惊讶!)并打印一个未初始化的int值.