Setiap contoh dari keanehan itu dipasangkan dengan kasus elipsis tunggal biasa.
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; };
Dugaan saya adalah bahwa elipsis ganda memiliki arti yang sama _ArgTypes..., ...
, yaitu perluasan template variadic diikuti oleh daftar varargs gaya C.
Ini adalah tes yang mendukung teori itu… Saya pikir kita memiliki pemenang baru untuk operator semu terburuk yang pernah ada.
Sunting: Ini tampaknya konforman. §8.3.5 / 3 menjelaskan satu cara untuk membentuk daftar parameter sebagai
parameter-deklarasi-daftar opt ... opt
Jadi elipsis ganda dibentuk oleh daftar-deklarasi parameter yang diakhiri dengan paket parameter, diikuti oleh elipsis lain.
Koma murni opsional; §8.3.5 / 4 memang mengatakan
Di mana secara sintaksis benar dan di mana "..." bukan bagian dari deklarator-abstrak, ", ..." adalah sinonim dengan "...".
Ini ada di dalam deklarator-abstrak, [edit] tetapi Johannes membuat poin yang bagus bahwa mereka merujuk ke deklarator-abstrak dalam deklarasi parameter. Saya bertanya-tanya mengapa mereka tidak mengatakan "bagian dari deklarasi parameter", dan mengapa kalimat itu bukan hanya catatan informatif…
Selain itu, va_begin()
in <cstdarg>
membutuhkan parameter sebelum daftar varargs, sehingga prototipe yang f(...)
secara khusus diizinkan oleh C ++ tidak berguna. Referensi silang dengan C99, ini ilegal di dataran C. Jadi, ini paling aneh.
Catatan penggunaan
Berdasarkan permintaan, berikut demonstrasi elipsis ganda:
#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 );
}
...
diikuti oleh...
.