От последния официален стандарт, C++14, първата ви инициализация не е двусмислена. [over.match.list]:
![въведете описание на изображението тук](https://i.stack.imgur.com/tucov.png)
Тъй като не съществуват конструктори на инициализатор-списък, ние влизаме във "втората фаза". А сега разгледайте [over.best.ics]/4:
![въведете описание на изображението тук](https://i.stack.imgur.com/g6NEE.png)
Нашият елемент е {0}
. Следователно това не позволява (дефинирано от потребителя) преобразуване {0}
-> A
за конструктора за копиране. Ясно е, че това не се прилага, ако не сме във втората фаза на [over.match.list], така че за вашия пример с B c({0})
, не възниква инициализация на списък за c
и се вземат предвид и двата конструктора.
CWG брой 1467
Първата инициализация в момента е също толкова двусмислена, колкото и втората. Компилаторите просто не са внедрили CWG #1467< /strong> все още - неговата резолюция премахна точка (4.5), цитирана по-горе.
Вижте #2076, който избира да отмени промяната:
Резолюцията на проблем 1467 направи някои правдоподобни конструкции зле оформени. Например,
struct A { A(int); };
struct B { B(A); };
B b{{0}};
Това вече е двусмислено, тъй като текстът, забраняващ дефинирани от потребителя преобразувания за конструктори за копиране и преместване на B
, беше премахнат от 13.3.3.1 [over.best.ics] параграф 4.
„Текстът“ е гореспоменатата точка. Ричард Смит предлага следната формулировка:
За типове, които не са класове, ние позволяваме инициализация от списък с единичен елемент за извършване на копие само ако елементът в списъка сам по себе си не е списък (13.3.3.1.5 [over.ics.list] bullet 9.1). Аналогичното правило за този случай би било да се добави отново водещият символ в 13.3.3.1 [over.best.ics] параграф 4, но само в случай, че самият инициализатор е списък с инициализатор:
втората фаза на 13.3.1.7 [over.match.list], когато списъкът с инициализатор има точно един елемент, който сам по себе си е списък с инициализатор, където целта е първият параметър на конструктор
от клас X
, а преобразуването е до X
или препратка към (евентуално cv-квалифициран) X
,
Тъй като инициализаторът {0}
сам по себе си е списък с инициализатори, този куршум ще направи първата ви инициализация отново добре оформена.
person
Columbo
schedule
09.09.2015
{}
никога не предполага списък с инициализатор, но версията на родител()
винаги го прави, дори когато няма конструктор на списък с инициализатор. Този отговор дава известна информация, но не и окончателен отговор. stackoverflow.com/questions/29851502/ - person Galik   schedule 09.09.2015