その奇妙さのすべてのインスタンスは、通常の単一の省略記号のケースとペアになります。
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は、パラメータリストを次のように形成する1つの方法を説明しています
パラメータ宣言リストopt ... opt
したがって、二重の省略記号は、パラメータパックで終了するパラメータ宣言リストと、それに続く別の省略記号で構成されます。
コンマはオプションです。§8.3.5/ 4は言う
構文的に正しく、「...」が抽象宣言子の一部ではない場合、「、...」は「...」と同義です。
これは抽象宣言子内にありますが、ヨハネスはパラメーター宣言内の抽象宣言子を参照していることを指摘しています。なぜ彼らが「パラメータ宣言の一部」と言わなかったのか、そしてなぜその文は単なる情報としてのメモではないのか…。
さらに、va_begin()
in <cstdarg>
はvarargsリストの前にパラメーターを必要とするため、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 );
}
...
後にはが続き...
ます。