parameter - c++ template with type



“......”標記的含義是什麼? 即參數包中的雙省略號運算符 (2)

在瀏覽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
{ /* ... */ };

那麼,這個令牌的含義是什麼?

編輯:看起來像修剪“......”問題標題為“...”,我確實是指“......”。 :)


Answer #1

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

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

一個示例實例是:

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

問候,調頻。


Answer #2

這種古怪的每一個例子都與一個常規單個省略號的案例配對。

  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很好地指出它們指的是參數聲明中的抽象聲明。 我想知道他們為什麼沒有說“參數聲明的一部分”,以及為什麼這句話不僅僅是一個信息記錄......

此外, <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 );
}




variadic-templates