什么是“… …”令牌的含义? 即参数包中的双省略号运算符

在浏览gcc当前的新C ++ 11头文件的过程中,我偶然发现了“……”令牌。 你可以检查,下面的代码编译罚款 [通过ideone.com]。

template <typename T> struct X { /* ... */ }; template <typename T, typename ... U> struct X<T(U......)> // this line is the important one { /* ... */ }; 

那么,这个令牌的含义是什么?

编辑:看起来像修剪“……”问题标题为“…”,我确实是指“……”。 🙂

每一个奇怪的事例都与一个单一的省略号的情况配对。

  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..., ...意义相似,即可_ArgTypes..., ...参数模板扩展后跟一个C样式可变参数列表。

这是一个支持这个理论的testing …我认为我们有史以来最差的伪操作者的新赢家。

编辑:这似乎是符合。 §8.3.5/ 3描述了一种形成参数列表的方式

参数声明列表optopt

所以双省略是由一个以参数包结尾的参数声明列表形成的,后面是另一个省略号。

逗号纯粹是可选的; §8.3.5/ 4确实说

在句法正确的地方,“…”不是抽象声明的一部分,“,…”与“…”是同义的。

在一个抽象声明中,但是Johannes很好地指出它们是指参数声明中的一个抽象声明。 我想知道他们为什么不说“参数声明的一部分”,为什么这个句子不仅仅是一个有用的信息。

此外, <cstdarg> va_begin()需要varargs列表前的参数,所以C ++专门允许的原型f(...)是无用的。 与C99交叉引用,在C中是非法的,所以这是最奇怪的。

使用说明

根据要求, 这是一个双省略的演示 :

 #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 ); } 

在vs2015分离逗号是模板版本中必不可less的:

  template <typename T, typename ... U> struct X<T(U...,...)> {};// this line is the important one 

一个示例实例是:

  X<int(int...)> my_va_func; 

问候,FM。