Considera questo codice:
#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);
}
Questo stampa:
vector overload
int overload
Perché questo non produce un errore di compilazione a causa della risoluzione ambigua del sovraccarico? Se il secondo costruttore viene rimosso, otteniamo vector overload
due volte. Come / secondo quale metrica è int
una corrispondenza inequivocabilmente migliore {}
di std::vector<int>
?
La firma del costruttore può sicuramente essere ulteriormente ritagliata, ma sono appena stato ingannato da un codice equivalente e voglio assicurarmi che nulla di importante venga perso per questa domanda.
{}
effettivamente fa in alcuni casi speciali, ma non è generalmente corretto (per cominciare, std::vector<int> x = {};
funziona, std::vector <int> x = 0;
non lo fa). Non è semplice come " {}
assegna zero".
struct A { int x = 5; }; A a = {};
non assegna zero in alcun senso, costruisce un A
con a.x = 5
. Questo è diverso A a = { 0 };
, che viene inizializzato a.x
su 0. Lo zero non è inerente a {}
, è inerente al modo in cui ogni tipo è costruito di default o inizializzato dal valore. Vedi qui , qui e qui .
{}
come un blocco di codice, assegna 0 alle variabili - esempio: const char x = {}; è impostato su 0 (null char), lo stesso per int ecc.