这种奇怪现象的每个实例都与常规单个省略号的情况配对。
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 样式可变参数列表。
这是一个测试支持这个理论……我认为我们有一个新的最差伪运算符的获胜者。
Edit:这看起来确实是符合的。 §8.3.5/3 描述了一种形成参数列表的方法:
parameter-declaration-listopt ...opt
因此,双省略号是由以参数包结尾的参数声明列表,后跟另一个省略号形成的。
逗号纯粹是可选的; §8.3.5/4确实说
在语法正确且“...”不是抽象声明符的一部分的情况下,“, ...”与“...”同义。
This is在抽象声明符中,[edit]但 Johannes 提出了一个很好的观点,即他们指的是参数声明中的抽象声明符。我想知道为什么他们没有说“参数声明的一部分”,以及为什么这句话不仅仅是一个信息注释......
此外,va_begin()
in <cstdarg>
在可变参数列表之前需要一个参数,所以原型f(...)
C++特别允许的没有用。与 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 );
}