[gnu++0x] Variadic Template based Array Class



  • Hey Leute
    Ich versuche, eine Template basierte, multidimensionale Array Klasse zu programmieren
    Hier der Code :

    typedef unsigned int uint;
    
    template<typename T, uint First , uint...Rest>
    struct A
    {
        typedef A<T,Rest...>::Array Array[First] ; //cannot expand ‘Rest ...’ into a fixed-length argument list 
    
    };
    
    template<typename T , uint First>
    struct A<T,First>
    {
        typedef T Array[First] ;
    };
    

    Kennt jemand ein funktionierendes Workout ?

    MFG
    Speed



  • typedef A<T,Rest...>::Array Array[First] ;
    

    Hier fehlt das zweite Argument.



  • drakon schrieb:

    typedef A<T,Rest...>::Array Array[First] ;
    

    Hier fehlt das zweite Argument.

    Das ist ja der Sinn dabei; dadurch entsteht ja eine Rekursion mit einer Abbruchbedingung.
    Folgendes funktionierendes Beispiel hat mich dazu Inspiriert :

    template<typename T>
    void print_comma_separated_list(T value)
    {
        std::cout<<value<<std::endl;
    }
    
    template<typename First,typename ... Rest>
    void print_comma_separated_list(First first,Rest ... rest)
    {
        std::cout<<first<<",";
        print_comma_separated_list(rest...);
    }
    

  • Administrator

    Kann es grad nicht testen, da ich keinen geeigneten Kompiler zur Verfügung habe, aber meiner Meinung nach fehlt da ein typename :

    typedef unsigned int uint; 
    
    template<typename T, uint First , uint...Rest> 
    struct A 
    { 
        typedef typename A<T,Rest...>::Array Array[First];
              //^^^^^^^^
    }; 
    
    template<typename T , uint First> 
    struct A<T,First> 
    { 
        typedef T Array[First] ; 
    };
    

    Grüssli



  • Dravere schrieb:

    Kann es grad nicht testen, da ich keinen geeigneten Kompiler zur Verfügung habe, aber meiner Meinung nach fehlt da ein typename :

    typedef unsigned int uint; 
    
    template<typename T, uint First , uint...Rest> 
    struct A 
    { 
        typedef typename A<T,Rest...>::Array Array[First];
              //^^^^^^^^
    }; 
    
    template<typename T , uint First> 
    struct A<T,First> 
    { 
        typedef T Array[First] ; 
    };
    

    Grüssli

    Tatsächlich fehlt da ein Typename; löst allerdings nicht das Problem für welches ich ein Workout suche :

    template <int a , int...b>
    struct A : A<b...> // unimplementiert
    {};
    
    template <int a>
    struct A<a>{};
    
    //komischerweise funktioniert diese endlosschleife :
    
    template <int a , int...b>
    struct A : A<1,1,b...>
    {};
    
    template <int a>
    struct A<a>{};
    

    Im Endeffekt suche ich ein konstrukt, dass das obige Simuliert.

    MFG
    Speed



  • Etwa so?

    #include <iostream>
    #include <typeinfo>
    
    template<typename T, unsigned... dims >
    struct A; // <-- das hier braucht der Compiler (noch).
    
    template<typename T, unsigned dim1, unsigned...dims>
    struct A<T, dim1, dims...>
    {
      typedef typename A<T, dims...>::array array[dim1];
    };
    
    template<typename T, unsigned dim1>
    struct A<T, dim1>
    {
      typedef T array[dim1];
    };
    
    int main()
    {
      A<char, 1, 2, 3, 4, 5>::array x;
    
      std::cout << typeid(x).name() << std::endl;
    }
    

    So schlängelt man sich an den noch nicht implementierten Teilen vorbei. Allerdings sollte dein ursprünglicher Code in der Zukunft auch irgendwann funktionieren.



  • Danke, es funktioniert!

    MFG
    Speed

    ps : welches Flag muss man setzten, damit GCC eine Warnung ausgibt, sobald die Array-grenzen überschritten werden?



  • Sofern die Indices nicht zur Compilezeit bekannt sind, kann der gcc selbst das nicht. Du kannst zu Debugzwecken -fmudflap -lmudflap mit angeben, aber in Release-Binaries würde ich das vermeiden (stumpf zu langsam). Ansonsten ist valgrind eine große Hilfe.

    Oder du könntest schlicht std::vector benutzen und mit .at(i) darauf zugreifen - das schmeißt ggf. std::out_of_range.


Anmelden zum Antworten