template arrays



  • gibt es nicht die möglichkeit einem template ein array als argument zu
    übergeben? das array bekommt dabei noch die größe übergeben.

    ich hab glaube ich sowas schonmal gesehen

    template<class T, int N, (T &array)[N]>
    

    sowas in der richtung gabs doch mal. (kann sein das das für was anderes war.



  • In deinem Fall könnte eine mögliche Antwort so aussehen:

    template<class T, int N, class Array = vector<T>> 	
    class XY;
    


  • Meinst du:

    template<class T, int N>
    void foo(T (&array)[N])
    {}
    

    ?



  • genau das meinte ich. (brauch ich nicht oft deswegen habichs vergessen 🙄 )

    allerdings löst das mein problem nicht ganz.

    das hauptproblem ist die übergabe eines literals als template-parameter.

    tepmlate <const char *name>
    

    das funktioniert allerdings nicht mit werten, die nicht exportierbar sind.

    (warum eigentlich, mit z.b. int gehts auch (func<42>) )

    genau das möchte ich aber, sprich den string an die template-klasse
    übergeben, ohne den ctor oder eine memberfunktion zu benutzen.

    class test
    {
    public:
        class2<"test"> value;
    };
    


  • Wieso brauchst du das? Wieso muss der Wert zur Compilezeit bekannt sein, und was spricht gegen den Konstruktor?



  • es ist einfacher wenn man den namen direkt im template angeben kann, als im
    ctor erstmal alle member so zu initialisieren. brauchen tue ich das für einen
    serialisierer wo es sehr praktisch wäre, den member mit namen anzusprechen,
    statt mit dem typ.

    mithilfe von ein paar (bösen) makros kann man das ganze gut implementieren, ohne
    das der benutzer vergisst, den ctor anzupassen (ok, gäbe eh einen kompilerfehler,
    aber schön sieht das nicht aus).



  • template<typename T>
    struct class2
    {
        void do_something()
        {
            std::cout << T::name;
        }
    };
    class test
    {
    public:
        static const char* name;
        class2<test> value;
    };
    
    const char* test::name = "test";
    

    Vielleicht so?



  • nicht ganz, der name ist nicht der klassenname (dummes beispiel von mir), sondern
    der der variablen.

    class c
    {
    public:
        property<float, "m_value"> m_value;
    
        // als makro:
    
        Property(float, m_value);
    };
    

    sowas wäre ideal.

    immer alle werte im ctor oder außerhalb der klasse zu initalisieren ist kein
    schönes design



  • Wie willst du auf das Property zugreifen oder reicht nur das setzen oder nur definieren? Und warum willst du ueberhaupt Properties?

    immer alle werte im ctor oder außerhalb der klasse zu initalisieren ist kein schönes design

    Gib mal ein Beispiel, wahrscheinlich hast du nur schlecht designed. 🙂 Auch mussen sie irgendwo initialisiert werden, arbeit spart man sich kaum. Als Alternative bieten sich noch Initialisierungslisten (Konstruktor) an.



  • ok 🙂

    ich möchte eine methode entwickeln um klassen und ihre member zu seralisieren.
    dazu bietet sich XML an. normalerweise müsste jede klasse eine serialsie methode
    haben. das möchte ich vermeiden. dazu gibt es eine template klasse "Property",
    von der man objekte anlegen kann, die sich (fast) genau wie die normalen
    datentypen verwenden lassen. damit das aber 1. vernünftig lesbar ist und 2.
    erweiterbar ist, möchte ich den namen jedes members als kennung verwenden.

    die frage ist nur: wie komme ich an den namen ohne ihn im ctor einzeln hin-
    scheiben zu müssen?



  • die vorlage schrieb:

    normalerweise müsste jede klasse eine serialsie methode
    haben. das möchte ich vermeiden.

    Dann würden sich wahrscheinlich freie Funktionen empfehlen (oder je nachdem eine separate Klasse). Ich würde diese Arbeit nämlich eher auslagern und nicht in der Klasse selbst machen - zum Beispiel wäre es von Vorteil, wenn nicht jedes Objekt einen grossen Overhead für die Serialisierung hätte. Dann kommt dir auch zugute, dass du bei einer Anpassung der Serialisierung nicht alle Klassen abändern musst.

    Du musst ja beim Speichern/Laden so oder so direkt über den Namen auf die Member zugreifen, von daher kannst du dir den String dazu erstellen. Zum Beispiel:

    // Zu serialisierende Klasse
    class MyClass
    {
        public:
            // ...
        private:
            float a;         // Member ganz normal
            OtherClass b;
    };
    
    // Hier ist Write() eine Funktion, die etwas in eine Datei schreibt (ich kenne 
    // deinen Code schliesslich nicht genau) - der Einfachheit halber als Template.
    // Das kannst du natürlich entsprechend an deine Schnittstelle anpassen...
    template <typename T>
    void Write(const T& var, const char* description);
    
    // Makro für übersichtlichere Schreibweise
    #define WRITE(CLASS, MEMBER) Write(CLASS.MEMBER, #MEMBER)
    
    // Deine freie Serialisierungsfunktion
    void Serialize(const MyClass& c)
    {
        WRITE(c, a);
        WRITE(c, b);
    }
    

    Das ist jetzt einfach mal ein spontaner Vorschlag, ich weiss nicht genau, wie das in dein Design passt. Aber vielleicht hilfts dir ja... 🙂


Anmelden zum Antworten