Templateklassen und Konstruktoren mit variabler Parameterzahl



  • Hallo,

    Mein Vector-Typ sieht so aus:

    template<class T,int components>
    class Vec
    {
        private:
            T data[components];
        public:
            Vec();
    
    };
    

    Nun würde ich gern folgendes ermöglichen:

    Vec<int,3> v1 (1,2,3);
    Vec<int,2> v2 (1,2);
    

    Ist es irgendwie möglich, die Anzahl der Parameter im Konstruktor vom Wert "components" abhängig zu machen ?

    Ich könnts zwar mit Konstruktor Überladung realisieren, da components bei mir nur im Bereich [1,6] liegt, aber ich suche eine elegantere Lösung.



  • Du koenntest eine feste anzahl von parametern nehmen und immer mit default args und halt immer nur die 1. components parameter nutzen. den typ der ungenutzen parameter koenntest du per template meta programming auf nen typ ohne elemente wie struct{} setzen, so das da kein overhead entstehen sollte, aber dadurch hat man nauterlich immer ne obergrenze fuer die maximale anzahl und manch ein compiler koennte da langsamen code generieren.
    Wie waer's denn mit ner factory?

    Vec<double,4> v=VecFac(v)<<1<<2<<1<<2;
    

    mit sowas wie

    template<class T,unsigned N,unsigned P=0> class VecFacClass {
      Vec<T,N>& v;
    public:
      VecFacClass(Vec<T,N>& v):v(v) {}
      VecFacClass<T,N,P+1> operator<<(T val) { v.data[P]=val; }
    };
    template<class T,unsigned N> class VecFacClass<T,N,N> { };
    
    template<class T,unsigned N> VecFacClass<T,N> VecFac(Vec<T,N>& v) { return v; }
    

    Vielleicht koennte man auf operator= verzichten und den copy ctor nehmen, wenn man etwas trickst und z.b. den default ctor der array elemente verhindert.



  • hmm mist, das klappt ja so gar nicht,man ich sollte erst denken...
    also:

    template<class T,unsigned N> class Vec {
      char data[sizeof(T)*N];
    public:
      T& get(unsigned n) { return *reinterpret_cast<T*>(data+n*sizeof(T)); }
      Vec(VecFac<T,N,N>) { }
    };
    
    template<class T,unsigned N,unsigned P=0> class VecFacClass {
      Vec<T,N>& v;
    public:
      VecFacClass(Vec<T,N>& v):v(v) {}
      VecFacClass<T,N,P+1> operator<<(T val) { new(&(v.get(P)) (val);return v; }
    };
    template<class T,unsigned N> class VecFacClass<T,N,N> { };
    
    template<class T,unsigned N> VecFacClass<T,N> VecFac(Vec<T,N>& v) { return v; }
    

    wenn dre compiler alles inlined sollte das doch klappen?



  • @Thomas
    Das is grausam...

    @yusha
    Ich würde mir mal den Vector in der STL zu gemühte führen, bzw. wie man ihn anwendet. Selbst wenn du was eigenes programmieren willst ist es eine gute Orientierung.



  • Was gehen sollte, wäre das Array direkt zu übergeben, also

    template<class T,int components>
    class Vec
    {
        private:
            T data[components];
        public:
            Vec(T array[components]);
    
    };
    

    Aufruf dann mit:
    int a[] = { 1,2,3 };
    Vec<int, 3> v(a);

    oder aber mit den VA makros zu arbeiten: Vec(...)
    Ist aber natürlich fehleranfälliger, da keine Typüberprüfung dann stattfindet.

    Leider unterstützt C++ keine VarArg-Template Parameter, sonst könnte man die Typen der Parameter direkt angeben, also z.B. Vec<int, int, int> und der Konstruktor würde dann entsprechend viele Parameter haben... (habe ich (und andere) zwar für den neuen Standard C++0x vorgeschlagen, aber die Umsetzung ist noch völlig unklar).



  • varargs gehen nur bei builtins afaik


Anmelden zum Antworten