令牌的含义是什么"... ..."?即参数包上的双省略号运算符

What is the meaning of "... ..." token? i.e. double ellipsis operator on parameter pack

本文关键字:省略号 运算符 参数 是什么 令牌      更新时间:2023-10-16

在浏览gcc当前新c++ 11头文件的实现时,我偶然发现了"......"令牌。您可以检查,下面的代码编译良好[通过godbolt.org]。

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..., ...,即一个可变的模板展开,后面跟着一个c风格的可变变量列表。

这里有一个支持该理论的测试,我认为我们有一个新的最糟糕的伪操作符。

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

parameter-declaration-list <子>选择…<子>选择

因此,双省略号由以参数包结尾的参数声明列表组成,后面跟着另一个省略号。

逗号是可选的;§8.3.5/4没有说

语法正确,"…"不是抽象声明器的一部分,",…是"…"的同义词。

这个在一个抽象声明器中,[edit]但是Johannes提出了一个很好的观点,他们在参数声明中引用了一个抽象声明器。我想知道为什么他们没有说"参数声明的一部分",为什么那句话不只是一个信息注释…

此外,<cstdarg>中的va_begin()在变量列表之前需要一个参数,因此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 %sn", std::string( "world!" ) );
    wrap_printf( &std::fprintf, stderr, std::string( "Error %d" ), 5 );
}

on vs2015中分隔逗号在模板版本中是必不可少的:

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

一个实例化的例子是:

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

问候,FM。