Pertimbangkan kode ini:
#include <vector>
#include <iostream>
enum class A
{
X, Y
};
struct Test
{
Test(const std::vector<double>&, const std::vector<int>& = {}, A = A::X)
{ std::cout << "vector overload" << std::endl; }
Test(const std::vector<double>&, int, A = A::X)
{ std::cout << "int overload" << std::endl; }
};
int main()
{
std::vector<double> v;
Test t1(v);
Test t2(v, {}, A::X);
}
Ini mencetak:
vector overload
int overload
Mengapa ini tidak menghasilkan kesalahan kompilasi karena resolusi kelebihan yang ambigu? Jika konstruktor kedua dihapus, kami mendapatkan vector overload
dua kali. Bagaimana / dengan metrik manakah int
kecocokan yang pasti lebih baik {}
daripada std::vector<int>
?
Tanda tangan konstruktor pasti dapat dipangkas lebih lanjut, tapi saya baru saja diakali oleh sepotong kode yang setara dan ingin memastikan tidak ada yang penting yang hilang untuk pertanyaan ini.
c++
language-lawyer
overload-resolution
Max Langhof
sumber
sumber
{}
sebagai blok kode, berikan 0 ke variabel - contoh: const char x = {}; diatur ke 0 (null char), sama untuk int dll.{}
efektif dalam kasus-kasus khusus tertentu, tetapi umumnya tidak benar (untuk permulaan,std::vector<int> x = {};
bekerja,std::vector <int> x = 0;
tidak). Ini tidak sesederhana "{}
menetapkan nol".struct A { int x = 5; }; A a = {};
tidak menetapkan nol dalam arti apa pun, itu membangun sebuahA
dengana.x = 5
. Ini tidak sepertiA a = { 0 };
, yang menginisialisasia.x
ke 0. Nol tidak melekat pada{}
, itu melekat pada bagaimana setiap jenis dibangun secara default atau nilai-diinisialisasi. Lihat di sini , di sini dan di sini .Jawaban:
Ada di [over.ics.list] , beri penekanan pada saya
Ini
std::vector
diinisialisasi oleh konstruktor dan peluru dalam huruf tebal dianggap sebagai konversi yang didefinisikan pengguna. Sementara itu, bagi seorangint
, ini adalah konversi identitas, sehingga mengalahkan pangkat c'tor pertama.sumber
0
bertipeint
tetapi tidak mengetikstd::vector<int>
, bagaimana itu "seolah-olah" sesuai dengan sifat "tidak diketik"{}
?std::vector<int>
. Seperti yang Anda katakan, saya perkirakan "tipe parameter akhirnya memutuskan apa tipe argumennya", dan{}
"tipe" (bisa dikatakan)std::vector<int>
tidak perlu konversi (non-identitas) untuk menginisialisasi astd::vector<int>
. Standar itu jelas mengatakan ya, jadi begitu, tapi itu tidak masuk akal bagi saya. (Pikiran Anda, saya tidak berpendapat bahwa Anda atau standar salah, hanya mencoba untuk mendamaikan ini dengan model mental saya.)