Initialisierung einer Member-Referenz ueber Uniform Initialization
-
Hallo,
Wieso klappt Uniform Initialization fast ueberall, nur bei Member-Referenzen nicht?
struct foo {}; struct bar { bar(foo& f) : f{f} {} foo& f; }; int main() { foo f; bar b{f}; }
prog.cpp: In constructor 'bar::bar(foo&)':
prog.cpp:7:14: error: invalid initialization of non-const reference of type 'foo&' from an rvalue of type '<brace-enclosed initializer list>'Gruesse,
Der Kellerautomat
-
Musst du nicht <initializer_list> einbinden? (s. N3337, §8.5.4 / 2)
Eineinitializer_list
kann übrigens keine Referenzen halten.
-
Kellerautomat schrieb:
Wieso klappt Uniform Initialization fast ueberall, nur bei Member-Referenzen nicht?
Diese Frage ist zu ungenau und enthält zuviele Annahmen, um sinnvoll beantwortet werden zu können.
List-Initialisierung einer Referenz führt zur Erzeugung eines temporären Objektes aus der Liste. Die Referenz wird dann an das temporäre Objekt gebunden.
int x=0; const int& a = x; assert( &x == &a ); const int& b(x); assert( &x == &b ); const int& a{x}; assert( &x != &c );
-
Und ich dachte sie wollten die Initialisierung damit einheitlich und intuitiver gestallten.
-
Camper meint vermutlich diesen Punkt:
n3376 § 8.5.4/3 schrieb:
Otherwise, if T is a reference type, a prvalue temporary of the type referenced by T is list-initialized,
and the reference is bound to that temporary.Etwas weiter oben in der Aufzählung (und damit zuerst zu berücksichtigen) ist das hier:
n3376 § 8.5.4/3 schrieb:
Otherwise, if the initializer list has a single element of type E and either T is not a reference type or
its referenced type is reference-related to E, the object or reference is initialized from that elementWeil foo& und foo& reference-related sind (8.5.3/4) entspricht das einer ganz normalen Initialisierung und der Code von K11t ist korrekt. clang kompiliert ihn übrigens anstandslos.
-
prvreg schrieb:
Camper meint vermutlich diesen Punkt:
n3376 § 8.5.4/3 schrieb:
Otherwise, if T is a reference type, a prvalue temporary of the type referenced by T is list-initialized,
and the reference is bound to that temporary.Etwas weiter oben in der Aufzählung (und damit zuerst zu berücksichtigen) ist das hier:
n3376 § 8.5.4/3 schrieb:
Otherwise, if the initializer list has a single element of type E and either T is not a reference type or
its referenced type is reference-related to E, the object or reference is initialized from that elementWeil foo& und foo& reference-related sind (8.5.3/4) entspricht das einer ganz normalen Initialisierung und der Code von K11t ist korrekt. clang kompiliert ihn übrigens anstandslos.
Das wäre dann ein Defekt im gegenwärtigen Standard. "Ready"-Status läuft ja darauf hinaus, dass diese Änderung im nächsten TR drin sein wird.