Code:
std::vector<int> x{1,2,3,4};
std::array<int, 4> y{{1,2,3,4}};
Warum brauche ich doppelte geschweifte Klammern für std :: array?
Code:
std::vector<int> x{1,2,3,4};
std::array<int, 4> y{{1,2,3,4}};
Warum brauche ich doppelte geschweifte Klammern für std :: array?
-Werrorsowieso für Code, den ich geschrieben habe, also schadet es meiner Portabilität nicht. Die Laufleistung anderer kann variieren, wenn sie Leichtgewichte sind oder Header-Dateien enthalten müssen, die von Leichtgewichten geschrieben wurden :-)
Antworten:
std::array<T, N>ist ein Aggregat: Es gibt keine vom Benutzer deklarierten Konstruktoren, nicht einmal einen, der a nimmt std::initializer_list. Die Initialisierung mit geschweiften Klammern erfolgt mit der aggregierten Initialisierung , einer Funktion von C ++, die von C geerbt wurde.
Der "alte Stil" der Aggregatinitialisierung verwendet Folgendes =:
std::array<int, 4> y = { { 1, 2, 3, 4 } };
Bei dieser alten Art der Aggregatinitialisierung können zusätzliche Klammern entfernt werden. Dies entspricht also:
std::array<int, 4> y = { 1, 2, 3, 4 };
Diese zusätzlichen Klammern dürfen jedoch nur "in einer Deklaration der Form T x = { a };" (C ++ 11 §8.5.1 / 11) entfernt werden, dh wenn der alte Stil =verwendet wird. Diese Regel, die die Klammerelision zulässt, gilt nicht für die direkte Listeninitialisierung. Eine Fußnote lautet hier: "Klammern können bei anderen Verwendungen der Listeninitialisierung nicht entfernt werden."
Zu dieser Einschränkung gibt es einen Fehlerbericht: CWG-Fehler Nr. 1270 . Wenn die vorgeschlagene Entschließung angenommen wird, ist die Klammerentfernung für andere Formen der Listeninitialisierung zulässig, und Folgendes ist wohlgeformt:
std::array<int, 4> y{ 1, 2, 3, 4 };
(Hutspitze an Ville Voutilainen, um den Fehlerbericht zu finden.)
array?
std::array<int> y = {1,2,3,4};mit einer Warnung von Clang arbeitet, die Klammern vorschlägt , anstatt eines schweren Fehlers darüber, dass bei Verwendung der direkten Listeninitialisierung keine Klammern um die Initialisierung des Unterobjekts weggelassen werden dürfen.
Weil std::vectorbietet einen Konstruktor, der a aufnimmt std::initializer_list<T>, während er std::arraykeine Konstruktoren hat und die {1, 2, 3, 4}geschweifte Init-Liste tatsächlich nicht als std::initializer_list, sondern als aggregierte Initialisierung für das innere C-artige Array von interpretiert wird std::array(daher kommt der zweite Satz von Klammern: Eins für std::arrayeine für das innere C-Style-Member-Array).
std::arrayoder erhalten Sie nur eine Warnung?std::array<int,4> y{1,2,3,4};funktioniert bei mir.