Saat menelusuri implementasi gcc saat ini untuk header C ++ 11 yang baru, saya menemukan token "......". Anda dapat memeriksa, bahwa kode berikut dapat dikompilasi dengan baik [via ideone.com].
template <typename T>
struct X
{ /* ... */ };
template <typename T, typename ... U>
struct X<T(U......)> // this line is the important one
{ /* ... */ };
Lantas, apa artinya token ini?
edit: Sepertinya SO dipangkas "......" pada judul pertanyaan menjadi "...", maksud saya benar-benar "......". :)
c++
c++11
variadic-templates
Vitus
sumber
sumber
...
diikuti oleh...
.U...
diikuti oleh...
. Sangat aneh.<functional>
dan<type_traits>
, selalu dalam konteks daftar argumen fungsi di dalam parameter templat.Jawaban:
Setiap contoh dari keanehan itu dipasangkan dengan kasus elipsis tunggal biasa.
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
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
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 yangf(...)
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:
sumber
std::is_function
'svalue
harus benar bahkan jika fungsi ini C varargs satu dan karena T (U ...) yang tidak cocok untuk fungsi tersebut, Anda perlu kegilaan ini. Misalnya int f (int, char, ...) cocok dengan T (U ......) persis dengan T = int, U = {int, char} dan token varargs "...".void (int...)
sini, the...
bukan bagian dari deklarator-abstrakint
, oleh karena itu ia identik denganvoid(int, ...)
. Jika Anda akan menulisvoid(T...)
danT
merupakan paket parameter template,...
akan menjadi bagian dari deklarator-abstrak, dan karenanya tidak akan setara denganvoid(T, ...)
.f(...)
banyak digunakan sebagai kelebihan beban fungsi fallback dalam metaprogramming template, di mana informasi ini tidak diperlukan (dan di mana fungsinya bahkan tidak benar-benar dipanggil).pada vs2015, memisahkan koma sangat penting dalam versi template:
contoh contoh adalah:
salam, FM.
sumber