Statische konstante Initialisierungsliste in Klasse



  • 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_list kann auf jedes Array Zugriff bieten, bzw. es wrappen. Das es keine speziellen Copy-Semantics gibt, isst dabei nicht wichtig, es geht hier nur darum was initializer_list kann 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?


  • Mod

    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.


Anmelden zum Antworten