2013-06-07 8 views

Antwort

37

Ihr Problem hat mit zu tun: ist ein Aggregat, während struct Y nicht ist. Hier ist der Standard Zitat über Aggregate (8.5.1):

ein Aggregat ist, ein Array oder eine Klasse (Abschnitt 9) ohne Benutzer bereitgestellten Konstruktoren (12.1), ohne Verstrebung-oder-gleich-Initialisierer für nicht statische Datenelemente (9.2), keine privaten oder geschützten nicht statischen Datenelemente (Abschnitt 11), keine Basisklassen (Abschnitt 10) und keine virtuellen Funktionen (10.3).

Diese Klausel gibt an, dass, wenn eine class eine Basisklasse hat, es kein Aggregat ist. Hier hat struct Ystruct X als eine Basisklasse und kann daher kein Aggregattyp sein.

In Bezug auf das besondere Problem, das Sie haben, nehmen Sie die folgende Klausel von der Norm:

Wenn ein Aggregat durch eine Initialisierungsliste initialisiert wird, wie in 8.5.4 angegeben, werden die Elemente der Initialisiererliste genommen als Initialisierer für die Mitglieder des Aggregats, in steigender Subskription oder Mitgliederordnung. Jedes Member wird aus der entsprechenden Initialisierungsklausel initialisiert. Wenn die Initialisierungsklausel ein Ausdruck ist und eine Konvertierungskonvertierung (8.5.4) erforderlich ist, um den Ausdruck zu konvertieren, ist das Programm schlecht formatiert.

Wenn Sie das tun X x = {0} wird Aggregat Initialisierung initialisiert a-0 verwendet. Wenn Sie jedoch Y y = {0} tun, da struct Y kein Aggregat-Typ ist, sucht der Compiler nach einem geeigneten Konstruktor. Da keiner der implizit generierten Konstruktoren (Standard, Kopieren und Verschieben) irgendetwas mit einer einzelnen Ganzzahl machen kann, lehnt der Compiler Ihren Code ab.


diese Konstrukteurs-Lookup In Bezug auf die Fehlermeldungen von Klirren ++ ein wenig mehr explizit über das, was der Compiler tatsächlich versucht, zu tun (online example):

Y Y = {0}; 
^ ~~~ 

main.cpp:5:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const Y &' for 1st argument 

struct Y : public X {}; 
    ^

main.cpp:5:8: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'Y &&' for 1st argument 

struct Y : public X {}; 
    ^

main.cpp:5:8: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided 

Hinweis, dass es a proposal erweitern Aggregat-Initialisierung, um Ihren Anwendungsfall zu unterstützen, und es in C++ 17 gemacht. Wenn ich es richtig lese, macht es Ihr Beispiel mit der von Ihnen erwarteten Semantik gültig. Sie müssen also nur auf einen C++ 17-kompatiblen Compiler warten.

+1

'clang ++ -std = C++ 1z' ​​Version 4.0.1 kompiliert, ' g ++ -std = C++ 17' Version 7.2.1 kompiliert, aber Visual Studio 2017 'cl' Version 19.12.25816 noch nicht –

Verwandte Themen