Statische konstante Initialisierungsliste in Klasse



  • Nathan schrieb:

    Die Fehlermeldung sagt doch, was der Fehler ist.
    Mache aus dem const ein constexpr und es funzt.

    Danke. Ich hatte die Fehlermeldung so verstanden, dass auf der rechten Seite das constexpr fehlt. Was ist den im Fall einer Variablen überhaupt der Unterschied zwischen constexpr und const?



  • 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?



  • Der Ansatz sieht irre aus (was zum Teufel soll das Array und was willst du damit tun?). Siehe auch meine Signatur.



  • 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?

    Ja?

    std::vector<int> vec( std::begin(arr), std::end(arr) ); /// Edit: Ich bin doof. 's gibt ja std::begin/end...
    


  • 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?

    Du irrst 😉

    using std::begin; using std::end;
    vector<int> vec(begin(array), end(array));
    

    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};
    

    bzw.

    std::vector<unsigned> vec(49);
    std::iota(begin(vec), end(vec), 1);
    

    Alles seit C++11.



  • Sone schrieb:

    std::vector vec(arr, arr + sizeof(arr) / sizeof(*arr));
    

    👎



  • 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.


Anmelden zum Antworten