在浏览gcc当前新C ++ 11标头的实现时,我偶然发现了“......”令牌。您可以检查以下代码compiles fine [via ideone.com]。
template <typename T>
struct X
{ /* ... */ };
template <typename T, typename ... U>
struct X<T(U......)> // this line is the important one
{ /* ... */ };
那么,这个令牌的含义是什么?
编辑:看起来如此修剪“......”的问题标题为“......”,我的意思是“......”。 :)
答案 0 :(得分:78)
该奇怪的每个实例都与常规单省略号的情况配对。
template<typename _Res, typename... _ArgTypes>
struct _Weak_result_type_impl<_Res(_ArgTypes...)>
{ typedef _Res result_type; };
template<typename _Res, typename... _ArgTypes>
struct _Weak_result_type_impl<_Res(_ArgTypes......)>
{ typedef _Res result_type; };
template<typename _Res, typename... _ArgTypes>
struct _Weak_result_type_impl<_Res(_ArgTypes...) const>
{ typedef _Res result_type; };
template<typename _Res, typename... _ArgTypes>
struct _Weak_result_type_impl<_Res(_ArgTypes......) const>
{ typedef _Res result_type; };
我的猜测是双省略号与_ArgTypes..., ...
的含义相似,即可变参数模板扩展后跟一个C风格的varargs列表。
Here's a test支持这个理论......我认为我们有一个新的胜利者,因为有史以来最糟糕的伪运营商。
修改:这似乎符合要求。 §8.3.5/ 3描述了将参数列表形成为
的一种方法parameter-declaration-list opt ... opt
因此,双省略号由参数声明列表以参数包结尾,后跟另一个省略号组成。
逗号纯粹是可选的; §8.3.5/ 4确实说
在语法正确且“......”不是抽象声明符的一部分的地方,“,...”与“...”同义。
这个是在一个抽象声明器中, [edit] 但是约翰尼斯提出了一个很好的观点,即他们指的是参数声明中的抽象声明符。我想知道他们为什么不说“参数声明的一部分”,以及为什么这句话不只是一个内容丰富的说明......
此外,va_begin()
中的<cstdarg>
在varargs列表之前需要一个参数,因此C ++特别允许的原型f(...)
是无用的。与C99交叉引用,在C语言中是非法的。所以,这是最奇怪的。
使用说明
根据请求,双省略号的here is a demonstration:
#include <cstdio>
#include <string>
template< typename T >
T const &printf_helper( T const &x )
{ return x; }
char const *printf_helper( std::string const &x )
{ return x.c_str(); }
template< typename ... Req, typename ... Given >
int wrap_printf( int (*fn)( Req... ... ), Given ... args ) {
return fn( printf_helper( args ) ... );
}
int main() {
wrap_printf( &std::printf, "Hello %s\n", std::string( "world!" ) );
wrap_printf( &std::fprintf, stderr, std::string( "Error %d" ), 5 );
}
答案 1 :(得分:2)
分隔逗号在模板版本中是必不可少的:
template <typename T, typename ... U>
struct X<T(U...,...)> {};// this line is the important one
示例实例化是:
X<int(int...)> my_va_func;
的问候, FM。