这种奇怪的每个实例都与一个常规的单个省略号的情况配对。
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 样式的可变参数列表。
这是一个支持该理论的测试......我认为我们有一个新的赢家,有史以来最差的伪操作员。
编辑:这似乎是一致的。§8.3.5/3 描述了一种形成参数列表的方法
参数声明列表opt ... opt
因此,双省略号由以参数包结尾的参数声明列表形成,然后是另一个省略号。
逗号纯粹是可选的;§8.3.5/4 确实说
在语法正确且“...”不是抽象声明符的一部分的情况下,“, ...”与“...”同义。
这是在一个抽象声明符中,[编辑]但 Johannes 提出了一个很好的观点,即他们指的是参数声明中的一个抽象声明符。我想知道他们为什么不说“参数声明的一部分”,以及为什么这句话不仅仅是一个信息性注释……</p>
此外,va_begin()
在<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 );
}