Statische konstante Initialisierungsliste in Klasse
-
nonli schrieb:
Sone schrieb:
std::vector vec(arr, arr + sizeof(arr) / sizeof(*arr));
Jaja ich weiß. Schon editiert. Das war C++98.
Ah shit! Da war ja nicht einmal eine richtige Template-Id!

Well well, shame on me.
-
TNA schrieb:
nonli schrieb:
Die initializer_list aus C++11 ist praktisch immer eine schlechte Idee, nimm lieber
static constexpr unsigned init[]. Arrays haben mit C++11 ein Upgrade erfahren, gibt eigentlich keinen Grund mehr, die nicht zu benutzen.Der Grund ist, dass man mit Arrays nicht so komfortabel einen vector initialisieren kann, oder irre ich mich da?
Wenn du C++11 verwenden kannst. Wieso solltest du ein std::array in einen std::vector stopfen wollen? Welchen Grund gibt es dafür?
-
Sone schrieb:
Der Ansatz sieht irre aus (was zum Teufel soll das Array und was willst du damit tun?). Siehe auch meine Signatur.
Falls die Frage an mich gerichtet war: Ich möchte eine für alle Instanzen gleiche, konstante Initialisierungsliste erstellen um damit Kontainer mit immer dem selben Inhalt zu initialisieren. Das Ganze ist eher eine theoretische Spielerei die dazu dienen soll C++11 Features anzuwenden. Hat keinen direkten, praktischen Hintergrund.
-
Die Frage ist wieso er so ein Array verwendet. Er braucht es definitiv nicht, da bin ich mir zu 99% sicher.
Edit: Ahja, zum Lernen. Naja.
-
out schrieb:
Wenn du C++11 verwenden kannst. Wieso solltest du ein std::array in einen std::vector stopfen wollen? Welchen Grund gibt es dafür?
Wieso std::array? Ich will eigentlich ein std::initializer_list verwenden.
-
nonli schrieb:
Du irrst

using std::begin; using std::end; vector<int> vec(begin(array), end(array));Ok, das lasse ich noch gerade als komfortabel durchgehen wobei
vector<int> vec(init);doch komfortabler wäre.
nonli schrieb:
Ansonsten kannst du den Vektor auch gleich direkt füllen
std::vector<unsigned> vec = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18, 19,20,21,22,23,24,25,26,27,28,29,30,31,32,33, 34,35,36,37,38,39,40,41,42,34,44,45,46,47,48,49};Das wollte ich gerade vermeiden, das an mehreren Stellen ausschreiben zu müssen.
nonli schrieb:
bzw.
std::vector<unsigned> vec(49); std::iota(begin(vec), end(vec), 1);Alles seit C++11.
Das ist in der Tat ne tolle Sache und kannte ich noch nicht. Hat allerdings deutlich höhere Laufzeitkosten oder? (Ich weiß, dass das hier nicht relevant ist, nur aus Interesse).
-
Ne andere Methode wäre natürlich, einfach einen static constexp vector zu nehmen, aber ich dachte das eine std::initializer_list zum initialisieren vielleicht zweckmäßiger wäre.
-
TNA schrieb:
Das ist in der Tat ne tolle Sache und kannte ich noch nicht. Hat allerdings deutlich höhere Laufzeitkosten oder? (Ich weiß, dass das hier nicht relevant ist, nur aus Interesse).
ich würde spontan tippen, dass iota schneller ist.
-
TNA schrieb:
out schrieb:
Wenn du C++11 verwenden kannst. Wieso solltest du ein std::array in einen std::vector stopfen wollen? Welchen Grund gibt es dafür?
Wieso std::array? Ich will eigentlich ein std::initializer_list verwenden.
initializer_list ist kein gewöhnlicher Container. Es hat einige Eigenschaften wie bspw. dass es die Elemente auf die es verweist gar nicht selber hält oder gar besitzt.
-
Sone schrieb:
std::vector<int> vec( std::begin(arr), std::end(arr) ); /// Edit: Ich bin doof. 's gibt ja std::begin/end...Es ist ätzend, dass Du ständig Deine Beiträge derart editierst, dass die ganze Scheiße die vorher da stand, ausgebügelt wurde, und die nachfolgenden Beiträge nur noch verwirren.
Höre entweder ganz auf zu antworten, wenn Du Dir nicht zu 100% sicher bist, oder streiche den Müll der vorher da stand einfach nur durch.Das hier war noch ein harmloser Fall aber es musste mal gesagt werden.
Und Deine Standardreaktion, dass ich sowieso nur ein Unreg bin, kannst Du Dir direkt sparen. Ich war schon im Forum, als Du noch in die Hosen gemacht hast.
-
Sone schrieb:
initializer_list ist kein gewöhnlicher Container. Es hat einige Eigenschaften wie bspw. dass es die Elemente auf die es verweist gar nicht selber hält oder gar besitzt.
Wie so oft bei deinen Posts: Das Gegenteil ist der Fall.
initializer_list ist kein gewöhnlicher Container. Er hat einige Eigenschaften wie bspw. dass es die Elemente auf die es verweist selber hält und besitzt. Er beschützt sie bestmöglich und zeigt sie immer nur als const-Referenz, es gibt keine Möglichkeit, sie rauszumoven. Er ist quasi immutable. Darum kann er kopiert werden ohne die unterliegenden Elemente mitzukopieren.
Dieses Verhalten ist unintuitiv und schädlich für die Performance. Das ist einer der Gründe, weshalb die uniform Initialisation Mist ist.
-
nonli schrieb:
Er hat einige Eigenschaften wie bspw. dass es die Elemente auf die es verweist selber hält und besitzt.
Besitz zeigt sich mMn dadurch, dass jede Instanz eigene Elemente hat.
Das es sie hält, stimmt vielleicht - wie man halten halt definiert.
Aber:Copying an initializer list does not copy the underlying elements.
Daher würde ich nicht von "Besitz" sprechen. Gerade wenn initializer_list die Elemente nicht selber allokiert oder zerstört.
-
Es ist jedenfalls falsch zu denken, die initializer_list sei nur ein Proxy auf ein bestehendes Array.
-
nonli schrieb:
Es ist jedenfalls falsch zu denken, die initializer_list sei nur ein Proxy auf ein bestehendes Array.
Machst du da extra eine Anspielung auf cppreferences Artikel?
An object of type std::initializer_list<T> is a lightweight proxy object that provides access to an array of objects of type T.
-
"an array" ist zwar nicht falsch, kann aber unterschiedlich verstanden werden. Deine Posts behaupten, initializer_list sei ein Proxy auf ein beliebiges Array. Das ist falsch, initializer_list ist nämlich ein Proxy auf ein Array, das von allen initializer_lists gemeinsam besessen und verwaltet wird. Ein bestehendes Array muss erst zum initializer_lists e.V. kopiert werden.
-
Also doch ein Proxy.
Deine Posts behaupten, initializer_list sei ein Proxy auf ein beliebiges Array.
Jo. So ist es nämlich, theoretisch. Der Compiler (bzw. Hersteller) kann damit machen was er auch immer will. Und
initializer_listkann auf jedes Array Zugriff bieten, bzw. es wrappen. Das es keine speziellen Copy-Semantics gibt, isst dabei nicht wichtig, es geht hier nur darum wasinitializer_listkann und was nicht. Und es kann auf jedes beliebige Array Zugriff bieten.Das ist falsch, initializer_list ist nämlich ein Proxy auf ein Array
Aha.
das von allen initializer_lists gemeinsam besessen und verwaltet wird.
Aber es ist nicht wichtig, ob eine bestimmte Menge von initializer_lists etwas tut. Hauptsache ist: initializer_list verweist auf ein Array. Das wars.
Ein bestehendes Array muss erst zum initializer_lists e.V. kopiert werden.
Wohin kopiert?
-
struct foo { static constexpr std::initializer_list<int> bar = { 0 }; };hat, der defekten Formulierung des aktuellen Standards zufolge, undefiniertes Verhalten, wenn foo::bar später verwendet wird (Das Beispiel in 8.5.4/6 widerspricht dem Text und ist nicht normativ). Dieser Fehler wurde im aktuellen Entwurf korrigiert.
Diese Korrektur ist zwar auch unbrauchbar:
The array has the same lifetime as any other temporary object (12.2 [class.temporary]), except that initializing an initializer_list object from the array extends the lifetime of the array exactly like binding a reference to a temporary.
Da ein initializer_list-Objekt nicht "from [an] array" initialisiert wird, ist diese Formulierung offensichtlich auch verunglückt.
Die Absicht dürfte allerdings klar sein. Praktisch dürfte es keinen vernünftigen Grund geben, initializer_list Objekte als Member zu verwenden. initialisierer_list ist kein Container.
-
camper schrieb:
Die Absicht dürfte allerdings klar sein. Praktisch dürfte es keinen vernünftigen Grund geben, initializer_list Objekte als Member zu verwenden. initialisierer_list ist kein Container.
Die Idee war, eine lange Initialisierungsliste die mehrfach verwendet wird quasi zu recyclen, um den Code nicht unnötig auszublähen. Ein Array tut es natürlich auch, aber da initializer_list eigentlich genau dazu da ist Container zu initialisieren schien mir das nahe liegend.