initializer_list
-
Sehe ich das richtig, dass man mit dem jahrelang durch das Kommitee gewanderten Sprachzusatz "initializer_list" und "aggregate initialization" immer noch kein Array von Objekten initialisieren kann, die nur Konstruktoren haben, die mehr als ein Argument haben, sowie nicht kopierbar sind?
-
Geht, wenn sie moveable sind.
(Musst move Ctor dazu ggf. defaulten)
http://ideone.com/OzEB3M
-
Leider sind sie zwar (optional) movable, aber das moven ist teuer, weil verbundene Entitäten umgebogen werden müssen, daher ist das leider keine Option
Ich hätte sie echt gerne in-place initialisiert 
-
moven ist teuer
Das ist in jedem Fall suboptimal.
Natürlich braucht man theoretisch keinen Move-Ctor
#include <iostream> class foo { public: foo(int, int) { std::cout << "i,i-Ctor\n"; } foo(const foo&) = delete; foo(foo&&) = delete; }; int main() { foo arr[]{ {1, 2}, {3, 4} }; // < copy-list-initialization für die Arrayelemente }Allerdings kann das möglicherweise nicht ästhetisch sein.
Undinitializer_listhat hier nichts verloren, dass hier ist in der Tat aggregate initialization (und das Aggregat ist natürlich das Array).
-
Was wirklich nicht geht sind
std::initializer_lists. S. Zeile 11, bzw. Arcoths Posting.#include <vector> struct gadget{ gadget(int,int){} gadget(const gadget&) = delete; gadget(gadget&&) = delete; }; int main(){ gadget gs[] = {{1,2}, {3,4}, {4,5}}; // passt std::vector<gadget> vgs{{1,2}, {3,4}, {4,5}}; // autsch! }
-
Was erwartet decimad, wenn er einen Container voll von Objekten haben möchte, die nicht kopierbar und nur ineffizient movebar sind?
-
Arcoth schrieb:
Aber Nathan, wieso verbreitest du Blödsinn? Natürlich braucht man keinen Move-Ctor
Nur nebenbei: Verbesserungsvorschläge kann man auch freundlich mitteilen. Du musst ausserdem nicht dauernd mit Worten wie "natürlich" so tun, als wäre jeder ein Idiot, der das nicht auf Anhieb weiss. Ansonsten musst du dich echt nicht wundern, warum du hier dauernd als Klugscheisser angesehen wirst.
-
Das habe ich natürlich schon vorher rauseditiert, weil mir das selbst klar war. Leider muss natürlich jeder das gleich QFTen.

Du musst ausserdem nicht dauernd mit Worten wie "natürlich" so tun, als wäre jeder ein Idiot, der das nicht auf Anhieb weiss.
Das tue ich auch nicht, denn 'natürlich' bedeutet hier, dass es einen direkten und einfachen Weg gibt, das zu erreichen, nicht, dass es jeder kennt.
Edit: Vielleicht sollte ich aufhören, 'natürlich' so zu verwenden... hehe
-
Zum moven:
Das moven biete ich bei diesen Objekten überhaupt nur an, damit man sie in einem Container speichern kann und ist nur Tradeoff zwischen Faulheit und Effizienz. Es handelt sich um Endpunkte von Datenkanälen und die dürfen im Speicher nunmal nicht hin- und herwandern (es sei denn, man biegt alle Referenzen um, was in diesem Fall zweifellos genau keine sind, aber diese Referenzen zu speichern kostet *trommelwirbel* Speicher).
Zum Thema:
Das Array müsste in einer Initialization-List eines Konstruktors initialisiert werden und der Compiler hat gemäkelt, das für Arrays keine Initializer-List-Syntax-Initialisierung zulässig ist, die "="-Syntax kommt da ja nicht in Frage, oder?
-
der Compiler hat gemäkelt, das für Arrays keine Initializer-List-Syntax-Initialisierung zulässig ist
... Compiler ist VC++, oder?
Wie wäre es mit Design überdenken? Das sieht alles widersprüchlich aus.
-
VC++ stimmt, den Rest überlese ich jetzt einfach mal

-
decimad schrieb:
VC++ stimmt, den Rest überlese ich jetzt einfach mal

Und wie sieht dein Plan aus?
std::vector<std::unique_ptr<>>?
-
Ich habe jetzt einfach 5 Member statt einem Feld von 5.

Wobei mich eines bezüglich Deines vorletzten Kommentars noch interessieren würde: Was genau sieht widersprüchlich aus, viel habe ich ja eigentlich gar nicht preisgegeben?
-
viel habe ich ja eigentlich gar nicht preisgegeben?
Nun, du willst Listen von nicht kopierbaren Elementen halten; Und das sie movebar sind, war eigentlich nicht vorgesehen. Also musstest du auf das Array verzichten... hmm.
Ich habe jetzt einfach 5 Member statt einem Feld von 5.
Wie oben gezeigt, dürftest du mit einem echten Array keine Schwierigkeiten haben, weil keine Kopien nötig sind.
-
Ja, dass ich per Template-Option anbiete, sie movebar zu machen, ist eigentlich inkonsequent. Aber irgendwie war ich da so im "flow" und es spart an einigen Stellen einige Zeilen Verwaltungs-Code, weil er so zentralisiert ist...
Eigentlich sind die Teile darauf ausgelegt, nicht bewegt zu werden. Der Move-"Hack" ist nur dafür da, dass ich nicht auf unique_ptr oder std::list ausweichen muss (was ich in der Vergangenheit dann auch tat, sogar in diesem Array-Fall, über den ich gerade nochmal drübergehe). Steht denn irgendwo geschrieben, dass Move effizient sein muss? Dachte es geht eher um Semantik, und die wird 1a eingehalten.Auf das Array verzichten muss ich leider, weil ich die Teile in einem Array nicht initialisiert bekomme, was ja offenbar ein VC++-Problem ist? Ansonsten wäre eigentlich alles in Butter.
-
weil ich die Teile in einem Array nicht initialisiert bekomme, was ja offenbar ein VC++-Problem ist?
Ganz vergessen, habe das glatt übersprungen. Dann bleibt dir wohl nichts anderes übrig. Vielleicht eine Union?

Steht denn irgendwo geschrieben, dass Move effizient sein muss?
Nein, vergiss das. Es ging nur darum, dass das Move gezwungenermaßen eingebaut wurde. Nicht weil das ein natürlicher Bestandteil der Klasse war.
-
no harm taken dude, let's carry on

-
zappenduster, eben kam mir die Idee, einfach ein uninitialized_array zu schreiben, aber die Jungs unter http://en.cppreference.com/w/cpp/types/aligned_storage hatten es schon fertig
Wollte ich nur für andere mitleidende VC++-Benutzer erwähnt haben...
-
boost::optionalginge u.U. auch.
Nimmt einem ab aufzupassen dass man nicht vergisst was freizugeben. Kostet dafür natürlich zusätzlich ein paar Byte + ein paar Zyklen CPU Zeit.
-
@hustbaer:
boost::optionalist praktisch einfach einunique_ptr. Wieso stattunique_ptr optionalnehmen?