Syntax Template Template Parameter



  • Ich habe ein Template: Bilder haben eine feste Groesse. Sie ist zur Compilezeit bekannt.

    template<int w, int h>
    class Image
    {
      static int const width;
      static int const height;
    };
    
    template<int w, int h>
    const int Image<w,h>::width = w;
    ...
    

    Darauf aufbauen moechte ich eine Klasse Framebuffer als Template realisieren. Dazu werden ebenfalls die Parameter w und h benoetigt. Die Parameter des Bildes moechte ich aber nicht direkt angeben, sondern die Klasse wie folgt instanziieren:

    Framebuffer< Image<1024,768> > frbuff;
    

    Die Werte 1024 und 768 werden intern fuer einige weitere Kompilezeitkonstanten benoetigt.

    Das Problem: Jetzt kann ich natuerlich etwas wie template<class T, int w, int h> basteln und Framebuffer getrennt von meinem Image dimensionieren. Will ich aber nicht. Auch ist das Problem, dass nicht nur Image akzeptiert wird sondern jeder Container. Was mir vorschwebt ist sowas wie:

    template< template Image<int w, int h> Img >
    class Framebuffer
    {
      char alphaPlane[w*h];
      Img* front;
      ...
    };
    

    Leider beschwert sich mein Compiler ueber die Syntax. Vielleicht gibt es auch eine andere Loesung via Type traits oder so. Btw. es sollte C++03 sein.



  • template<typename T>
    class Framebuffer
    {
      char alphaPlane[T::width*T::height];
      T* front;
      ...
    };
    


  • Ich wuerde mich gern auf meine Klasse Image beschraenken, da sie ein bestimmtes Speicherlayout hat. In deinem Beispiel wird jeder Container akzeptiert, der irgendwie width und height anbietet. Ich will ein Template, dass width und height als Parameter hat, aber diese aus dem Templateparameter Image holt. alphaPlane soll nur ein Beispiel sein, wie ich die Parameter verrechnen moechte. Leider kann ich auf width und height aus Image zugreifen, da die Initialisierungsreihenfolge fuer globale Variablen nicht festgelegt ist. Also muss ich mich auf die Templateparameter w und h aus Image stuetzen.



  • Das wird nicht funktionieren, da Du bei Template-Templates als Argument tatsächlich nur ein Template und keine konkrete Instanz angeben kannst. Folgendes würde aber gehen:

    template<int w, int h>
    class Image
    {
      static int const width = w;
      static int const height = h;
    };
    
    template<template< int w, int h > class Img, int w, int h>
    class Framebuffer
    {
        char alphaPane[w*h];
        typedef Img<w,h> theImage;
        Img<w,h>* front;
    };
    
    typedef Framebuffer<Image, 1024, 768> Fb;
    Fb::theImage image;
    Fb fb(&image);
    


  • knivil schrieb:

    Ich wuerde mich gern auf meine Klasse Image beschraenken, da sie ein bestimmtes Speicherlayout hat. In deinem Beispiel wird jeder Container akzeptiert, der irgendwie width und height anbietet. Ich will ein Template, dass width und height als Parameter hat, aber diese aus dem Templateparameter Image holt. alphaPlane soll nur ein Beispiel sein, wie ich die Parameter verrechnen moechte. Leider kann ich auf width und height aus Image zugreifen, da die Initialisierungsreihenfolge fuer globale Variablen nicht festgelegt ist. Also muss ich mich auf die Templateparameter w und h aus Image stuetzen.

    Wie LordJaxom vermute ich auch, dass das nicht geht (auch wenn LordJaxom es etwas unglücklich formuliert hat). Die Frage ist also:
    1. Warum kannst du w und h nicht direkt übergeben? Wenn die aufrufende Funktion keine Templatefunktion ist, die den Typ eben nicht beschränkt (was ja nicht in deinem Sinne ist), müsstest du ja an w und h rankommen.
    2. Was erhoffst du dir für einen Gewinn durch die Beschränkung? Bessere Fehlermeldungen? Eventuell könnten BOOST_STATIC_ASSERT() oder das Folgende helfen:

    template<typename T> class Framebuffer;//nicht definiert, führt bei Instantiierung zu Compilerfehler
    template<int w, int h> class Framebuffer<Image<w, h> >
    {
        //...
    };
    


  • Wenn Framebuffer sowieso immer mit Image arbeitet, welchen Sinn macht es dann, Image in Template-Parameter stopfen zu wollen? Schreib halt

    template<int w, int h> class Framebuffer {
      typedef Image<w, h> ImageType;
    
      char alphaPane[w * h];
      ImageType *front;
    };
    
    ...
    
    Framebuffer<1024, 768> fb;
    

Log in to reply