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?
-Werror
sowieso 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::vector
bietet einen Konstruktor, der a aufnimmt std::initializer_list<T>
, während er std::array
keine 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::array
eine für das innere C-Style-Member-Array).
std::array
oder erhalten Sie nur eine Warnung?std::array<int,4> y{1,2,3,4};
funktioniert bei mir.