Saya memiliki kelas-kelas itu:
#include <type_traits>
template <typename T>
class A {
public:
static_assert(std::is_default_constructible_v<T>);
};
struct B {
struct C {
int i = 0;
};
A<C> a_m;
};
int main() {
A<B::C> a;
}
Saat kompilasi, a_m
tidak bisa dibangun tetapi default a
.
Saat mengubah C
ke:
struct C {
int i;
};
semuanya baik-baik saja.
Diuji dengan Dentang 9.0.0.
C() {}
itu bekerja juga.static_assert
inA
gagal, tetapi jika Anda sebaliknya membangun bagianT
dalamA
(misalnya menempatkan anggota diT t;
sana), itu berfungsi dengan baik. Ketidakkonsistenan antara apa yang dikatakan oleh sifat itu dan apa yang sebenarnya mungkin terjadi ...const int x;
tidak valid tanpa penginisialisasi, murni karenaconst
dan perilaku inisialisasi tipe bawaan dan beberapa sejarah)Jawaban:
Ini dilarang baik oleh teks standar dan oleh beberapa implementasi utama seperti yang disebutkan dalam komentar, tetapi untuk alasan yang sama sekali tidak terkait.
Pertama, alasan "menurut buku": titik instantiasi
A<C>
adalah, menurut standar, tepat sebelum definisiB
, dan titik instantiasistd::is_default_constructible<C>
adalah tepat sebelum itu:Karena
C
jelas tidak lengkap pada saat itu, perilaku instantiatingstd::is_default_constructible<C>
tidak terdefinisi. Namun, lihat masalah inti 287 , yang akan mengubah aturan ini.Pada kenyataannya, ini ada hubungannya dengan NSDMI.
= 0
pada prinsipnya dapat merujuk pada hal-hal yangB
belum dinyatakan, sehingga implementasi tidak dapat benar-benar mencoba menguraikannya sampai selesaiB
.C
tidak ada konstruktor yang dideklarasikan.A<C>
, ia berpikir bahwaC
itu tidak lengkap.Seluruh area yang berurusan dengan wilayah yang diurai-tertunda ini sangat tidak ditentukan, disertai dengan divergensi implementasi. Mungkin perlu beberapa saat sebelum dibersihkan.
sumber
Perilaku yang tidak terdefinisi adalah:
sumber
C
sudah selesai, tetapiB
tidak. DanB::C
tergantung secara tidak langsung padaB
.C
memiliki templat konstruktor default dengan beberapa SFINAE aneh yang dapat mengubah jawaban jika diisiB
secara berbeda, maka tentu saja, sifatnya bergantung pada itu.