Array-Member initialisieren
-
Edit: Alles Quatsch. Habe lediglich einen Flüchtigkeitsfehler eingebaut

So funktionierts:std::array<std::atomic<int*>, N> a {{ { &arr[indices] }... }};
-
Warum kann ich
std::array<std::atomic<int*>, N>mit einerstd::initializer_list<std::initializer_list<int*>>initialisieren?
-
Jodocus schrieb:
Warum kann ich
std::array<std::atomic<int*>, N>mit einerstd::initializer_list<std::initializer_list<int*>>initialisieren?Weil kein entsprechender Konstruktor vorhanden ist? Du kannst lediglich Klassen mit einem
initializer_list<>Objekt initialisieren wenn ein entsprechender Konstruktor vorhanden ist. Aggregate haben keine vom User bereitgestellten Konstruktoren. Was in meinem (jetzt endlich) korrigierten Code verwendet wird, verwendetinitializer_listgar nicht.
-
Ich hab gefragt, warum ich es kann, da ich deinen Code so interpretiere (und eben array keinen solchen Konstruktor hat). Und da sind keine Initializer_lists drin? Was ist dann der Unterschied zwischen
std::array<std::atomic<int*>, N> a{ &arr[indices]... };std::array<std::atomic<int*>, N> a{{ &arr[indices]... }};und
std::array<std::atomic<int*>, N> a{{ { &arr[indices] }... }};?
Das erste ist die normale Aggregat-Initialisierung. Das zweite ist eine Aggregat-Initialisierung eines temporären Arrays, das dann kopiert wird? Und das dritte?
-
std::array<std::atomic<int*>, N> a{ &arr[indices]... };initialisiert jedes Element
en viastd::atomic<int*> e_n = &arr[n];Diese Form der initialisierung von
aist tatsächlich equivalent zu1std::array<std::atomic<int*>, N> a{{ &arr[indices]... }};Jedoch können die Klammern in diesem Fall weggelassen werden. In keinem der beiden Fälle wird ein temporäres Array oder
arrayerstellt. Es werden lediglich Temporaries durch copy-initialization benötigt. Dir ist sicherlich bekannt, dass auch instd::string s = "abc";eine Temporary erstellt wird?
Der Große Unterschied der nun in der dritten Variante ausgenutzt wird, ist dass
std::array<std::atomic<int*>, N> a{{ { &arr[indices] }... }};Eine Initialisierung a la
std::atomic<int*> e_n = {&arr[n]};impliziert - aber hier brauchen wir - dank der Regeln von list-initialization - keine Temporary, denn der Konstruktor von
en wird direkt mit&arr[n]aufgerufen.Wenn wir jedoch
std::array<std::atomic<int*>, N> a{ { &arr[indices] }... };schreiben, dann wird zuallererst versucht, dass interne Array mit
{ &arr[0] }zu initialisieren, was natürlich fehlschlägt.
---
1 Ich bin mir gerade nicht einmal sicher, ob die erste Variante standardkonform ist, da §8.5.1/11 was anderes suggeriert, aber da alle mir bekannten Implementierungen es per se annehmen, scheine ich da etwas falsch zu interpretieren
-
Arcoth schrieb:
Eine Initialisierung a la
std::atomic<int*> e_n = {&arr[n]};impliziert - aber hier brauchen wir - dank der Regeln von list-initialization - keine Temporary, denn der Konstruktor von
en wird direkt mit&arr[n]aufgerufen.Meinst du nicht eher, dass das
std::atomic<int*> e_n{&arr[n]}; // ohne =impliziert? Gemäß http://en.cppreference.com/w/cpp/language/list_initialization wäre das mit dem
=eine copy-list initialization und nicht direct.
-
Beide. In jeder Form von list-initialization werden die initializer-clauses stets direkt an den Konstruktor weitergeleitet - außer ein
initializer_listKonstruktor wird aufgerufen, was hier aber offensichtlich nicht der Fall ist.Edit: Was genau meinste gerade? Bin etwas verwirrt. Dass die Arrayelemente bei Aggregatinitialisierung stets mittels copy-initialization initialisiert werden, habe ich bereits aufgezeigt.
-
Arcoth schrieb:
Bin etwas verwirrt.
Hat sich erledigt, ich hab mir die Regeln im Standard noch mal durchgelesen. Danke!
-
Hab' auch mein vorhin erwähntes Problem gelöst:
1 Ich bin mir gerade nicht einmal sicher, ob die erste Variante standardkonform ist, da §8.5.1/11 was anderes suggeriert, aber da alle mir bekannten Implementierungen es per se annehmen, scheine ich da etwas falsch zu interpretieren
Dieser Paragraph wurde durch CWG #1270 angepasst, sodass
std::array<int, 1> arr{0};seit C++14 gültig ist.
-
Arcoth schrieb:
Edit: Was genau meinste gerade? Bin etwas verwirrt. Dass die Arrayelemente bei Aggregatinitialisierung stets mittels copy-initialization initialisiert werden, habe ich bereits aufgezeigt.
Was ich meinte, ist, dass eine List-Initialization à la
std::atomic<int*> e_n = {&arr[n]};Auch ein Temporary erzeugt, im Gegensatz zu
std::atomic<int*> e_n{&arr[n]};, wobei letzteres wohl bei
std::array<std::atomic<int*>, N> a{{ { &arr[indices] }... }};passiert.