Apa aturan yang std::is_constructible
menangani konstruktor pribadi? Diberikan kode berikut:
#include <iostream>
class Class {
private:
Class() { }
};
template <typename T>
class Test {
public:
static void test() {
std::cout
//<< std::is_constructible<Class>::value
<< std::is_constructible<T>::value
<< std::endl;
}
};
int main() {
Test<Class>::test();
}
Cetakan ini 0
( ideone ), yaitu, T
tidak dapat dibangun secara default.
Membatalkan komentar pada baris yang dikomentari, ia mencetak 11
( ideone ), jadi T
tiba-tiba menjadi default dibangun.
Saya dapat menemukan alasan untuk mendukung kedua hasil, tetapi saya tidak mengerti bagaimana memasukkan baris komentar mengubah hasil yang kedua. Apakah ini entah bagaimana melibatkan UB? Apakah ini bug kompiler? Atau std::is_constructible
benar-benar tidak konsisten?
c++
typetraits
Zennehoy
sumber
sumber
00
::value
versi ini mampu mengubah output dari yang datang sebelumnya juga: godbolt.org/z/zCy5xU Batalkan komentar pada baris yang dikomentari dan semuanya menjadi 1: dalam gcc.false
tetapi jika templat fungsi tidak dicommentasikan, tiba-tiba kembalitrue
: godbolt.org/z/zqxdk2Jawaban:
std::is_constructible
harus kembalifalse
dalam skenario ini karena konstruktor tidak dapat diakses.Seperti yang ditunjukkan di bawah pertanyaan, perilaku yang dijelaskan dalam pertanyaan disebabkan oleh bug di GCC / libstdc ++. Bug dilaporkan di sini , dan, menurut Bugzilla, terkait dengan jika tidak disebabkan oleh bug kontrol akses untuk kelas-kelas dalam fungsi templat yang tidak terselesaikan selama beberapa waktu. Hubungan antara kedua bug tersebut diambil dari komentar Bugzilla Jonathan Wakely yang tampaknya telah mendeteksi hubungan antara kedua bug terlebih dahulu.
Ini juga tersirat oleh fakta bahwa perilaku skenario ini di GCC menjadi benar ketika menghapus konstruktor alih-alih menjadikannya pribadi:
yang mencetak
0
dan00
masing - masing. Ini adalah output yangclang
benar (yang dengan benar melaporkan dalam skenario dengan konstruktor pribadi juga).Ini bisa menjelaskan perubahan perilaku yang diamati ketika berkomentar di baris, karena di dalam fungsi dalam templated struct, pemeriksaan akses tidak berfungsi dan melaporkan bahwa konstruktor dapat diakses ketika tidak. Ketika sifat diperiksa lagi di baris berikutnya atau mungkin di lokasi yang sama sekali berbeda (seperti halnya di sini ), itu sudah dipakai, dan dengan demikian menghasilkan jawaban yang salah.
sumber