La differenza può essere ridotto a
struct A { explicit A(int); };
struct B { B(int); };
void f(A);
void f(B);
int main() {
f({ 1 });
}
Su GCC questo non riesce, in conformità alla norma (che dice che per la lista di inizializzazione, costruttori espliciti sono considerate - in modo che possano produrre un'ambiguità - ma hanno semplicemente non sono autorizzati a essere selezionati). Clang accetta e chiama la seconda funzione.
Nel vostro caso, ciò che @Columbo dice nella sua risposta allo Direct list initialization compiles successfully, but normal direct initialization fails, why? si applica. Con la differenza che nel tuo caso, B(const B&);
non è più accettabile per Clang perché la conversione {0} -> B
avrebbe dovuto affrontare due possibilità: il costruttore esplicito o l'utilizzo ricorsivo del costruttore di copie una seconda volta. La prima opzione, come spiegato sopra, non verrà considerata da clang e questa volta si applica la spiegazione di @Columbo e il costruttore di copia non può essere utilizzato una seconda volta perché ciò richiederebbe una conversione definita dall'utente poiché abbiamo un singolo elemento (qui, 0
). Quindi nel sommario, solo il primo costruttore ha successo e viene preso.
Da quando ho capito il problema è sulle regole strane risoluzione di sovraccarico e alcuni potrebbe non essere in grado di seguire, ecco una spiegazione più intuitiva. Le regole che sono attivi sono, in ordine
Quindi per GCC si può utilizzare il costruttore esplicito direttamente, e in aggiunta da un singolo uso del costruttore di copie. Per clang, considera solo l'uso diretto del costruttore esplicito, e non lo userà indirettamente da una inizializzazione della copia-lista usando il costruttore di copie come GCC. Entrambi non prenderanno in considerazione l'utilizzo del costruttore di copie una seconda volta, ed è irrilevante qui.
fonte
2015-10-10 16:52:02
Duplicato di http://stackoverflow.com/q/32469979/3647361? – Columbo
@Columbo 'B (A)' è esplicito qui e http://stackoverflow.com/questions/32469979/direct-list-initialization-compiles-successfully-but-normal-direct-initializati sia gcc che clang ottengono lo stesso risultato ma qui è diverso. – stackcpp
La mia ipotesi è che è dovuto a diversi standard di default/supporto standard. –