Pertanyaan Apa saja 6 titik dalam paket parameter template? [duplikat]


Pertanyaan ini sudah memiliki jawaban di sini:

Sambil melihat ini pertanyaan saya menemukan diri saya di situs referensi cpp di mana saya melihat sintaks yang aneh dan baru bagi saya:

template<class Ret, class... Args>
struct is_function<Ret(Args......)volatile &&> : std::true_type {};

Ya, 6 titik! Awalnya saya pikir ini adalah kesalahan ketik, tetapi setelah memeriksa libstdc ++ sumber lagi di sana misalnya pada baris 444:

template<typename _Res, typename... _ArgTypes>
struct is_function<_Res(_ArgTypes......) volatile &&> : public true_type { };

Apakah ini sintaks yang valid? Dot dot dot, digunakan untuk mengemas dan membongkar paket parameter? Apa yang dilakukan 6 titik?


13
2017-12-21 23:06


asal


Jawaban:


Dalam hal ini, keduanya untuk tujuan yang berbeda. Yang pertama adalah untuk ekspansi paket parameter dan yang kedua adalah untuk daftar argumen variabel. Deklarasi khusus tersebut adalah untuk menangani fungsi-fungsi yang mengambil beberapa parameter reguler ditambah daftar argumen variabel.

Perbedaannya adalah antara waktu berjalan dan variabilitas waktu kompilasi. Suatu fungsi yang mengambil sejumlah variabel argumen pada saat run-time adalah spesial. Ini adalah fungsi tunggal yang dapat menangani sejumlah argumen variabel dari pemanggil:

void f(int x,...) // equivalent to void f(int x ...)
{
    // Do some run-time logic here to determine what to
    // do with parameters after x.
}

Ini berbeda dari gagasan bahwa kita ingin dapat memiliki template yang menggunakan berbagai fungsi dengan berbagai parameter yang dikenal pada waktu kompilasi. Sebagai contoh, kita bisa mendefinisikan sebuah template fungsi yang mengambil pointer ke fungsi dan memungkinkan jumlah dan jenis argumen bervariasi:

template <typename... Args>
void g(void (*function_ptr)(Args...)) 
{ 
    // We can do logic here to call function_ptr with the proper
    // number of arguments.
}

Diberikan fungsi-fungsi ini:

void f1(int);
void f2(int,float);

Anda dapat memanggil g dengan salah satu dari mereka:

g(f1); // fine
g(f2); // also fine

Namun

g(f); // error

Compiler tidak akan tahu apa yang harus digunakan untuk Args paket parameter di g.


8
2017-12-21 23:10



Kenapa libstdc++ menggunakan ... ... dalam penerapannya is_function? Jika kita lihat bagian cppreference untuk std :: is_function ini memberikan contoh penerapan dan mengatakan untuk yang pertama ... ... kasus:

// specialization for variadic functions such as std::printf
template<class Ret, class... Args>
struct is_function<Ret(Args......)> : std::true_type {};

jadi kita perlu set kedua ... untuk mencocokkan fungsi variadic seperti printf:

           Comma optional as per 8.3.5 [dcl.fct] 
           |
           v
Ret(Args... ...)
        ^   ^
        |   |
        Match a function with a variable number of arguments
            |
            and the function is a variadic function

Catatan, kami memiliki fungsi seperti fprintf bahwa dua argumen sebelum istilah variadic dan kita harus mencocokkannya juga. Memang jika kita menggunakan implementasi itu dan berusaha mencocokkan printf tanpa ... ... spesialisasi kemudian gagal lihat langsung.

Sudut bahasa ini tercakup dalam posting ini C ++ 11's enam titik:

Saya mucking di sekitar hari lain dan menemukan keanehan kecil yang menyenangkan ini:

template <typename... Args>
void foo(Args......);

Ternyata, ...... dapat benar-benar valid C ++ 11. Inilah yang terjadi ketika kompabilitas mundur bercampur dengan panas baru.

// Ini semua setara.

template <typename... Args> void foo1(Args......);
template <typename... Args> void foo2(Args... ...);
template <typename... Args> void foo3(Args..., ...);

Semoga yang terakhir menunjukkan apa yang terjadi di sini. [...]

Kenapa valid ini? Kita bisa melihatnya , ... identik dengan ... dari draft bagian standar C ++ 11 8.3.5  [dcl.fct] yang memiliki tata bahasa berikut:

parameter-declaration-clause:
  parameter-declaration-listopt...opt
  parameter-declaration-list , ...

dan berkata:

[...] Di mana secara sintaksis benar dan di mana "..." bukan bagian dari   deklarator abstrak, ", ..." identik dengan "...". [...]


54
2017-11-03 15:12