その奇妙さのすべてのインスタンスは、通常の単一の省略記号のケースとペアになっています。
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 は言う
構文的に正しく、「...」が抽象宣言子の一部でない場合、「, ...」は「...」と同義です。
これはabstract-declarator内にあります[編集]が、Johannesは、パラメーター宣言内のabstract-declaratorを参照していることを適切に指摘しています. なぜ彼らは「パラメータ宣言の一部」と言わなかったのか、そしてなぜその文は単なる情報メモではないのだろうか…</p>
さらに、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 );
}