Pertimbangkan kode berikut:
struct A
{
// No data members
//...
};
template<typename T, size_t N>
struct B : A
{
T data[N];
}
Ini adalah bagaimana Anda harus menginisialisasi B: B<int, 3> b = { {}, {1, 2, 3} };
Saya ingin menghindari {} kosong yang tidak perlu untuk kelas dasar. Ada solusi yang diusulkan oleh Jarod42 di sini , namun, itu tidak bekerja dengan inisialisasi default elemen: B<int, 3> b = {1, 2, 3};
baik-baik saja tetapi B<int, 3> b = {1};
tidak: b.data[1]
dan b.data[2]
tidak default diinisialisasi ke 0, dan terjadi kesalahan kompiler. Apakah ada cara (atau akan ada dengan c ++ 20) untuk "menyembunyikan" kelas dasar dari konstruksi?
c++
initialization
c++20
aggregate-initialization
pengguna7769147
sumber
sumber
template<class... Ts> B(Ts... args) : data{args...} {}
?Jawaban:
Solusi termudah adalah menambahkan konstruktor variadic:
Jika Anda memberikan lebih sedikit elemen dalam
{...}
daftar penginisialisasi daripadaN
, elemen yang tersisa dalam arraydata
akan diinisialisasi nilai olehT()
.sumber
B<Class, 5> b = {Class()};
Class
akan dibangun pertama dan kemudian dipindahkan, sementara dengan menggunakan inisialisasi agregatClass
akan dibuat di tempat, tidak ada langkah yang terlibatstd::tuple
argumen dan menggunakannya untuk membangun objek di tempat. Tetapi sintaksnya akan agak rumit.Karena C ++ 20 Anda dapat menggunakan inisialisasi yang ditunjuk dalam inisialisasi agregat .
sumber
Masih dengan konstruktor, Anda mungkin melakukan sesuatu seperti:
Demo
SFINAE dilakukan terutama untuk menghindari membuat konstruktor pseudo copy
B(B&)
.Anda akan memerlukan tag pribadi ekstra untuk mendukung
B<std::index_sequence<0, 1>, 42>
;-)sumber
((void)Is, T())...
? Bagaimana jika Anda hanya menghilangkannya? Bukankah elemen yang tersisa diinisialisasi nilai denganT()
secara default?Saya telah menemukan solusi lain yang (saya tidak tahu caranya) bekerja dengan sempurna dan menyelesaikan masalah yang kami diskusikan di bawah jawaban Evg
sumber
this->data
atauusing B_data::data;
mengaksesdata
di dalamB
.