Di C ++ 11 ada template variadic seperti ini:
template< class T, class... Args >
unique_ptr<T> make_unique( Args&&... args )
{
return unique_ptr<T>(new T(std::forward<Args>(args)...));
}
Ada beberapa keingintahuan tentang ini: Ekspresi std::forward<Args>(args)...
menggunakan keduanya Args
dan args
tetapi hanya satu ...
token. Selanjutnya std::forward
adalah fungsi template non-variadic yang hanya mengambil satu parameter template dan satu argumen. Apa aturan sintaks untuk itu (secara kasar)? Bagaimana itu bisa digeneralisasikan?
Juga: Dalam implementasi fungsi, elipsis ( ...
) berada di akhir ekspresi minat. Apakah ada alasan bahwa dalam daftar argumen template dan daftar parameter elipsis berada di tengah?
c++
c++11
variadic-templates
Ralph Tandetzky
sumber
sumber
...
muncul sebelum pengenal diperkenalkan. Saat menggunakan salah satu atau kedua jenis paket,...
muncul setelah pola ekspresi meluas.Jawaban:
Dalam konteks template variadic, elipsis
...
digunakan untuk membongkar paket parameter template jika muncul di sisi kanan ekspresi (panggil pola ekspresi ini sebentar). Aturannya adalah bahwa pola apa pun yang ada di sisi kiri...
akan diulang - pola yang tidak dikemas (sebut ekspresi sekarang) dipisahkan dengan koma,
.Ini dapat dipahami dengan baik dengan beberapa contoh. Misalkan Anda memiliki template fungsi ini:
Sekarang jika saya memanggil fungsi ini lewat
T
sebagai{int, char, short}
, maka setiap pemanggilan fungsi diperluas sebagai:Dalam kode yang Anda posting,
std::forward
ikuti pola keempat yang diilustrasikan olehn()
pemanggilan fungsi.Perhatikan perbedaan antara
x(args)...
dan diy(args...)
atas!Anda juga dapat menggunakan
...
untuk menginisialisasi array sebagai:yang diperluas menjadi ini:
Saya baru menyadari sebuah pola bahkan dapat menyertakan penentu akses seperti
public
, seperti yang ditunjukkan pada contoh berikut:Dalam contoh ini, polanya diperluas sebagai:
Artinya,
mixture
diturunkan secara publik dari semua kelas dasar.Semoga membantu.
sumber
x+args...
harus diperluas menjadix+arg0,x+arg1,x+arg2
, bukanx+arg0,arg1,arg2
....
berlaku untuk setiap entitas yang dapat diperluas dalam pola tersebut.x+args...
harus berkembang menjadix+arg0,x+arg1,x+arg2
, bukanx+arg0,arg1,arg2
.sizeof...(T)
tidak diperlukan di sana. Anda cukup menulis:int a[] = { ___ };
Berikut ini diambil dari pembicaraan "Template Variadic Funadic" oleh Andrei Alexandrescu di GoingNative 2012. Saya dapat merekomendasikannya untuk pengenalan yang baik tentang template variadic.
Ada dua hal yang dapat dilakukan dengan paket variadic. Dimungkinkan untuk diterapkan
sizeof...(vs)
untuk mendapatkan jumlah elemen dan memperluasnya.Aturan perluasan
Ekspansi berlanjut ke dalam ke luar. Saat memperluas dua daftar dalam langkah kunci, keduanya harus memiliki ukuran yang sama.
Contoh lainnya:
Memperluas semua
Ts
dalam daftar argumen templatA
dan kemudian fungsihun
diperluas dengan semuavs
.Memperluas semua
Ts
dalam daftar argumen templat dariA
dan semuavs
sebagai argumen fungsi untukhun
.Memperluas fungsi
hun
denganTs
danvs
dalam langkah kunci.catatan:
Ts
bukan tipe danvs
bukan nilai! Mereka adalah alias untuk daftar jenis / nilai. Salah satu daftar mungkin berpotensi kosong. Keduanya hanya mematuhi tindakan tertentu. Jadi hal berikut tidak mungkin:Lokus perluasan
Argumen fungsi
Daftar penginisialisasi
Penentu dasar
Daftar penginisialisasi anggota
Daftar argumen tempate
Hanya akan mengkompilasi jika ada kemungkinan cocok untuk argumen.
Tangkap daftar
Daftar atribut
Ini ada dalam spesifikasi, tetapi belum ada atribut yang dapat diekspresikan sebagai tipe.
sumber