Seperti yang saya tahu std::allocator<T>::construct
hanya membutuhkan dua parameter pada versi C ++ yang lebih lama; yang pertama adalah pointer ke memori mentah, yang tidak dibangun di mana kita ingin membangun objek bertipe T
dan yang kedua adalah nilai tipe elemen untuk menginisialisasi objek tersebut. Jadi copy-constructor dipanggil:
struct Foo {
Foo(int, int) { cout << "Foo(int, int)" << endl; }
/*explicit*/ Foo(int) { cout << "Foo(int)" << endl; }
Foo(const Foo&) { cout << "Foo(const Foo&)" << endl; }
};
int main(int argc, char* argv[]) {
allocator<Foo> a;
Foo* const p = a.allocate(200, NULL); // second parameter is required on C++98 but on C++11 it is optional
// Foo* const p = a.allocate(200); // works fine on C++11 but not on C++98
a.construct(p, 5, 7); // works on C++ 11 and up but not C++98
a.construct(p, 10);// works on both
a.destroy(p);
a.destroy(p + 1);
a.deallocate(p, 200);
std::cout << std::endl;
}
Mengapa pada C ++ 98
a.construct(p, 10)
memanggil copy constructor tetapi pada C ++ 11 dan di atas hanya memanggil constructor yang mengambil integer?Apakah ini berarti pada C ++ 11 karena beberapa optimasi Copy-penghilangan bunyi dlm percakapan bahkan jika konstruktor
Foo(int)
adalahexplicit
karya panggilan seperti:a.construct(p, 5)
bekerja pada C ++ 11 bahkan konstruktor adalahexplicit
apa yang saya yakin itu tidak bekerja pada C ++ 98 jikaFoo(int)
adalahexplicit
.Jika demikian maka jika saya mengkompilasi pernyataan itu dengan semacam
copy-elision
optimasi menonaktifkan akan menyebabkan kompiler gagal? Terima kasih.
Jawaban:
Ini karena deklarasi
construct
perubahan dalam C ++ 11 :Deklarasi pertama memanggil copy constructor, sedangkan deklarasi kedua memanggil constructor yang cocok dengan daftar argumen yang diberikan. Ini bisa menjadi konstruktor salin, tetapi juga konstruktor lain seperti yang Anda lihat dalam kode Anda.
a.construct(p, 10)
memanggil copy constructor di C ++ 98 karena10
secara implisit dikonversi keFoo
melaluiFoo(int)
constructor. Konversi ini tidak diperlukan di C ++ 11 karena ada konstruktor yang cocok yang mengambilint
(persis konstruktor yang digunakan untuk mengkonversi di C ++ 98). Ini juga alasan mengapa kode tidak berfungsi di C ++ 98 ketika Anda menambahkanexplicit
- tidak dapat mengonversikannya10
menjadiFoo
itu.sumber