delegating constructor und initializer-list
-
Hallo Leute,
wir hatten gerade eine kleine Diskussion, ohne befriedigendes Ergebnis und auch ein Studium des Standards brachte keine wirkliche Erhellung.
Frage: darf man delegating constructor und initializer-list mischen?
Und wenn ja, wie sind dann die Regeln, welche Initialisierung hat Vorrang und wird ggf. zweimal oder garantiert nur einmal initialisiert?Beispiel:
class A { public: A( double f ); A( int x, int y ); private: // das ging schon immer A( int x, double f ) : a( x ) , b( 0 ) , d( f ) {} int a, b; double d; }; // das geht jetzt auch A::A( double f ) : A( 0, f ) {} // aber geht das? A::A( int x, int y ) : A( x, 0.0 ) , b( y ) {}
Gibt's da einen Hinweis im Standard? Ich habe keinen gefunden ...
Der C++-Compiler im Visual Studio 12 kann letzteres nicht.error C3511: 'A' : a call to a delegating constructor shall be the only member-initializer
Gruß
Werner
-
Hallo,
ich kann dir leider keine Quelle nennen, aber ich bin mir ziemlich sicher, dass das geht.
Die einzige Einschränkung ist, dass der Ctor als erstes in der Liste stehen muss.
Also:// ok A::A( int x, int y ) : A( x, 0.0 ) , b( y ) {} // geht nicht A::A( int x, int y ) : b( y ) , A( x, 0.0 ) {}
Edit: Ähm...oder doch nicht?
http://en.cppreference.com/w/cpp/language/initializer_list schrieb:
If the name of the class itself appears as class-or-identifier in the member initializer list, then the list must consist of that one member initializer only; such constructor is known as the delegating constructor, and the constructor selected by the only member of the initializer list is the target constructor
Edit2:
(§12.6.2/6) A mem-initializer-list can delegate to another constructor of the constructor’s class using any class-or-decltype that denotes the constructor’s class itself. If a mem-initializer-id designates the constructor’s class, it shall be the only mem-initializer; the constructor is a delegating constructor, and the constructor selected by the is the target constructor. [...]
-
Wenn du den Konstruktor delegierst, macht es keinen Sinn noch eine Member-Variable zu initialisieren.
Ansonsten würder der Konstruktor der betreffenden Member-Variablen zweimal aufgerufen.
-
Hallo Jockelx,
Danke für die Antwort. Mein Kollege meinte das auch, dass es in einer zukünftigen VS-Version möglich ist.
Jetzt habe ich aber im Standard doch noch was gefunden:
Standard Kapitel 12 [class.base.init] schrieb:
If a mem-initializer-id designates the constructor’s class, it shall be the only mem-initializer; the constructor is a delegating constructor, ...
'the only' interpretiere ich so, dass außer dem 'delegating constructor' kein weiterer Member in der Liste stehen darf.
Ich stell mir das auch schwierig für den Compiler vor, so etwas aufzulösen. Es sei denn man nimmt ggf. eine doppelte Initialisierung in Kauf.
Gruß
Werner
-
coder777 schrieb:
Wenn du den Konstruktor delegierst, macht es keinen Sinn noch eine Member-Variable zu initialisieren.
Ansonsten würder der Konstruktor der betreffenden Member-Variablen zweimal aufgerufen.
Wenn du einen in-class initializer und ctor hast, dann wird die in-class initialization auch nicht ausgeführt. Genauso könnte man das ja hier auch regeln.