initalizer_list::size nicht constexpr



  • Du könntest Variadic templates nutzen und würdest dabei auch die drei anderen Konstruktoren sparen.

    Außerdem würde sich hier statt T p[dim] std::array<T, dim> anbieten, weil es automatisch kopiert und gemoved (scheiß wort) werden kann, ohne dass man im Compiler das selber machen muss.

    EDIT: Zu spät



  • Marthog schrieb:

    Außerdem würde sich hier statt T p[dim] std::array<T, dim> anbieten, weil es automatisch kopiert und gemoved (scheiß wort) werden kann, ohne dass man im Compiler das selber machen muss.

    Zu dumm, dass hier auch normale Arrays automatisch kopiert werden.



  • herr compiler schrieb:

    Marthog schrieb:

    Außerdem würde sich hier statt T p[dim] std::array<T, dim> anbieten, weil es automatisch kopiert und gemoved (scheiß wort) werden kann, ohne dass man im Compiler das selber machen muss.

    Zu dumm, dass hier auch normale Arrays automatisch kopiert werden.

    Default copy-constructor kopiert unter anderem POD types. Wie konnte ich das nur vergessen.



  • initializer_list::size keine constexpr und kann daher nicht in static_assert verwendet werden

    Weil es den Compilerherstellern ueberlassen ist, wie sie das implementieren. Es koennte auch ein std::vector in anderen Kleidern sein.



  • Das mit den variadic templates ist eine gute Idee, funktioniert auch. Brauche ich halt eine rekursive Hilfsfunktion, bisschen unschön aber ok.

    Dennoch finde ich es schwachsinnig, dass size keine constexpr ist. Nach der Definition kann ich ja so oder so keine Werte zu der Liste hinzufügen bzw. wegnehmen. Aber ich bin auch kein Experte :D.



  • Ich will zusätzlich einen Konstruktor anbieten, die die Initialisierung der Komponenten des Punktes über eine initializer_list ermöglicht

    Das macht keinen Sinn. Ein initializer_list -Konstruktor ist da sinnvoll, wo eine verschiedene Anzahl von Argumenten möglich ist (bspw. vector ).
    Deine Punkt-Klasse kann auch so dank list-initialization mit der entsprechenden Syntax initialisiert werden, dazu brauchst du keinen initializer_list -Konstruktor. Und variadic templates schon gar nicht, das ist noch unpassender.


  • Mod

    Nur der Vollständigkeit halber:
    Man kann die betreffende Parameterliste auch vorher erzeugen, nachteilig sind ggf. die schlechteren Fehlermeldungen. Andererseits wird der Code etwas einfacher, weil weniger Membertemplates benötigt werden. Lohnt nat. nur, wenn die Liste öfter gebraucht wird.

    template <typename... T> struct type_list;
    template <int N, typename T, typename = type_list<>> struct repeat;
    template <int N, typename T, typename... elems> struct repeat<N, T, type_list<elems...>>
        : repeat<N-1, T, type_list<T, elems...>> {};
    template <typename T, typename... elems> struct repeat<0, T,
    type_list<elems...>>
    {
        typedef type_list<elems...> type;
    };
    
    template <typename T, int dim = 2, typename = typename repeat<dim, T>::type>
    class Point;
    template <typename T, int dim, typename... elems>
    class Point<T, dim, type_list<elems...>>
    {
       public:
          Point(elems... v):
             p {v...}
          {}
    
       private:
          T p[dim];
    };
    


  • Danke für die Vorschläge und Workarounds.

    Ich hab mal im C++14 draft geschaut, dort sind begin(), end() und size() als constexpr deklariert. (18.9.2).



  • Sone schrieb:

    Das macht keinen Sinn. Ein initializer_list -Konstruktor ist da sinnvoll, wo eine verschiedene Anzahl von Argumenten möglich ist (bspw. vector ).

    Ist doch in der Point-Klasse auch der Fall. Oder allgemein einem mathematischen Vektor.

    Sone schrieb:

    Deine Punkt-Klasse kann auch so dank list-initialization mit der entsprechenden Syntax initialisiert werden

    Und wie sieht die Syntax aus?



  • Ist doch in der Point-Klasse auch der Fall.

    Nein. In der Point-Klasse, sprich: Einer Spezialisierung des Klassentemplates, ist die Zahl immer fest.


Anmelden zum Antworten