C++11 std::initializer_list & objekt-array



  • Hi,

    ich baue gerade eine Bibliothek von mir um und habe folgende tolle Idee:

    Vector3<float> verts[] = {
    	{0.0, 0.5, 0.0},
    	{-0.75, -0.5, 0.0},
    	{0.75, -0.5, 0.0}
    };
    

    Für "nicht-array" initialisierungen und zuweisungen habe ich:

    template <class type>
    class Vector3 {
    	...
    	Vector3(const std::initializer_list<type>& right);
    	Vector3& operator =(const std::initializer_list<type>& right);
    	...
    }
    

    Wie kriege ich es aber hin ein Array wie oben definiert zu konstruieren?
    Zur Zeit beschwert sich der Compiler:

    error: assigning to an array from an initializer list

    Über google kann ich leider nichts passendes finden. Einige Hilfreiche Sachen soweit konnten mir helfen und der teil im 2ten code-block oben funktioniert auch sauber aber wenn es um arrays geht, komme ich einfach nicht weiter.

    Danke für Hilfe

    Der Verzweifelte 🙂



  • Konstruieren müsste so gehen, aber die Fehlermeldung lässt vermuten, dass du versuchst, einem bereits konstruierten Array eine initializer_list zuzuweisen, was nicht geht. Ich glaube, std::array bringt einen solchen Zuweisungsoperator mit; versuch das mal statt eines nackten Arrays.



  • Ich versuche bei der Bibliothek nach Möglichkeit auf nix von der stdlib zuzugreifen.

    template <class type>
    class Triangle {
    protected:
    	Vector3<type> vertices[3];
    
    public:
    	Triangle() {
    		this->vertices = {
    			{0.0, 0.5, 0.0},
    			{-0.75, -0.5, 0.0},
    			{0.75, -0.5, 0.0}
    		};
    	}
    };
    

    So sieht der ganze ausschnitt vom code aus.



  • Versuch mal das ganze in die Initialisierungsliste zu schreiben. Das Objekt wird nämlich in deinem Konstruktor erst Standardinitialisiert und dann versuchst du das zu überschreiben, indem du dem nackschen Array eine initializer_list übergibst.
    Ganz arg reduziert versuchst du das:

    int ar[3];
        ar = {1, 2, 3};
    

    ... geht aber nicht, da ar schon in einen Zeiger zerfallen ist.
    (Spuckt bei mir auch denselben Error aus.)
    -> Schreib die Arrayinitialisierung im Konstruktor von Triangle in die Initialisierungsliste.

    class A
    {
        int ar[3];
    
        public:
            A() : ar({1, 2, 3}) {};
    };
    


  • Hi.

    Danke, das hat es schonmal zum funktionieren gebracht.

    Da ich aber einen initializer_list fähigen operator= schreiben und nutzen kann, würde ich trotzdem gerne wissen, ob und wie es möglich ist, das bereits initialisierte array neu zu setzen.

    Einzelne Elemente bzw. "nicht-arrays" mit dem operator funktioniert ja soweit

    this->vertices[0] = {0.0, 0.5, 0.0};
    

    Irgendwie muss es doch gehen, dass ich ohne stdlib container, nur mit einem array statisch oder dynamisch allokiert das zuweisen kann.

    Mein Wissenshungriger Kopf hätte gerne ein Nein mit Begründung oder einen Weg *g*, auch wenn mir dein Beispiel schon geholfen hat (Danke btw. :-)), mag ich fragen nicht einfach unbeantwortet wieder vergessen 😉



    1. Lasse den operator= weg, dann funktioniert bereits alles.
      Denn wenn du t={...} schreibst, wird das in t=Triangle{...} geändert und einen Konstruktor hast du schon.
    2. Copying a std::initializer_list does not copy the underlying objects.

    Du solltest deine Initialisierungsliste per value und nicht per const-reference übergeben (lass das const& weg).

    1. Es gibt keinen Grund auf die "stdlib", wie du sie nennst, zu verzichten. Insbesondere auf std::array<>, wenn du eh schon C++11 verwendest.
    2. Weshalb ist vertices protected? Mach es entweder public (würde ich empfehlen) oder private.


  • initializer_list ist auch Teil des Standards 😉

    Irgendwie muss es doch gehen, dass ich ohne stdlib container, nur mit einem array statisch oder dynamisch allokiert das zuweisen kann.

    Löschen und neu allokieren. Der Compiler weiß zu dem Zeitpunkt nicht mehr, dass es ein Array ist, er hat nur den Zeiger in der Hand. Du könntest dir auch einen Globalen operator= machen, der einen Zeiger und eine initializer_list annimmt, aber das würde ich lieber sein lassen, es gibt sicherlich gute Gründe, warum es das in der stdlib auch nicht gibt. Was hast du denn gegen die Standardbibliothek? Mit std::vector ginge das alles 100x leichter.

    Kannst dir natürlich auch schnell selbst einen Wrapper um ein Array ala std::vector schreiben, aber das hätte noch weniger Sinn.


Log in to reply