一般に、関数で C++11 可変個引数テンプレート機能を使用するには、可変個引数ベースの関数引数を関数引数リストの最後にする必要があります。例外が 1 つあります。C レベルの可変引数が存在する場合、それらは最後から 2 番目の引数であり、最後でなければなりません。
template < typename ...Args >
int super_printf( Something x, Args &&...a, ... );
私はときどき C++ についてランダムに考え、そのような機能をどのように実装できるのか疑問に思いました。最初に、通常の aからの引数の再帰的なピーリングについて考えました。次に、C レベルの可変引数はカスケードしないことを思い出しました。すぐにそれらを決定的な va_list に変更する必要があります。
template < typename ...Args >
int super_vaprintf( Something x, std::va_list &aa, Args &&...a );
// Note that "aa" is passed by reference.
template < typename ...Args >
int super_printf( Something x, Args &&...a, ... )
{
std::va_list args2;
int result;
va_start( args2, XXX ); // (A)
try {
result = super_vaprintf( x, args2, std::forward<Args>(a)... );
} catch ( ... ) {
va_end( args2 ); // (1)
throw;
}
va_end( args2 ); // (2)
return result;
// Can (1) and (2) be compacted with RAII using a custom deleter lambda
// in std::unique_ptr or something? Remember that "va_end" is a macro!
}
通常の C++ 可変長再帰ピーリングがsuper_vaprintf
呼び出しで発生します。行 (A) でXXX
、「a」または「a...」の代わりに何が入りますか? aが空の場合、代わりにxがそこにある場合はどうなりますか? 最後の質問が真である場合、xがない場合、私たちは台無しになります。可変引数以外に引数がないことを確認しますか? (もしそれが真なら、aが空のときにxを使用し、それ以外の場合に a を使用するようにコードを条件付けするにはどうすればよいでしょうか?)
...
ここでサポートが必要な場合は、C++11 標準のコピーを参照してください。ないようです。これは、C++ 委員会がこれを修正するために戻ってくるように要求するよう促しますが、C++ 可変引数がすべてを取得せずにそのような関数を呼び出す方法があるかどうかはわかりません。私が間違っている; 関数呼び出しで C++ と C の両方の可変引数を使用できますか? それとも、愚かな(テンプレート)インスタンス化のトリックに関して、ミキシングは宣言にのみ役立ちますか?