2012-11-16 15 views
7

Ich habe ein Problem mit variadische Template-Vorlagen:Template-Template-Syntax Probleme mit variadische Vorlagen

  template <typename T> class A { }; 
      template< template <typename> class T> class B { }; 
      template <template <typename> class T, typename parm> class C { typedef T<parm> type; }; 
      template <typename... types> class D { }; 
      template <template <typename...> class T, typename ... parms> class E { typedef T<parms...> type; }; 

      // How to pass list in list?? 
      template < template <typename...> class ...T, ???> 
      class F 
      { 
      }; 

zunächst eine Art der Vorlage passieren, kein Problem:

  A<int> a; //ok 

Jetzt möchte ich Erstellen Sie eine Instanz von B, aber keine Möglichkeit, die Vorlage Vorlage Parameter übergeben:

  B<A> b; // ok, but no chance to submit <int> inside A! 

Also ich muss die pa erweitern rameter Liste:

  C<A, int> c; // ok, this transport int as parm into A 

Jetzt habe ich mit variadische Vorlagen in üblichen Weise spielen:

  D<> d1; // ok 
      D<int, float, double> d2; //ok 

Parameter in den variadische Teil Passing ist auch Straße nach vorn:

  E<D> e1; //ok 
      E<D, double, float, int> e2; //ok 

ABER: Wenn ich will, Um eine Liste von Listen zu haben, finde ich keine Syntax, die es mir ermöglicht, Parameterlisten an die Liste der Typen zu übergeben. Was meine Absicht ist so etwas. aber auch das obige Beispiel zeigt, dass B<A<int>> b; ein Fehler ist! So könnte das folgende Beispiel nicht funktionieren :-(

  F< D< int, float>, D< int>, D <float, float, float> > f; 

Mein Ziel ist es, die Liste von Listen über Template-Spezialisierung entrollen. Irgendwelche Hinweise?

Meine Lösung, nachdem ich das Problem verstanden. Danke!

Jetzt kann ich meine variadic variadic Vorlagenvorlage wie im folgenden Beispiel ausrollen Das einfache Problem war, dass ich auf eine Vorlagenklasse und nicht auf einen einfachen Typ warte Manchmal kann die Lösung so einfach sein :-)

Das ist mein Arbeitsergebnis jetzt:

template <typename ... > class D; 

    template <typename Head, typename... types> 
    class D<Head, types...> 
    { 
     public: 
      static void Do() { cout << "AnyType" << endl; D<types...>::Do(); } 
    }; 

    template<> 
    class D<> 
    { 
     public: 
      static void Do() { cout << "End of D" << endl; } 
    }; 

    template < typename ...T> class H; 

    template < typename Head, typename ...T> 
    class H<Head, T...> 
    { 
     public: 
      static void Do() 
      { 
      cout << "unroll H" << endl; 
      cout << "Subtype " << endl; 
      Head::Do(); 
      H<T...>::Do(); 
      } 
    }; 

    template <> 
    class H<> 
    { 
     public: 
      static void Do() { cout << "End of H" << endl; } 
    }; 


    int main() 
    { 
     H< D<int,int,int>, D<float, double, int> >::Do(); 
     return 0; 
    } 

Antwort

2

Sie können eine variadische Spezialisierung auf einmal durch Spezialisierung auspacken:

template<typename...> struct S; 
template<> struct S<> { constexpr static int n = 0; }; 
template<template<typename...> class T, typename... Us, typename... Vs> 
struct S<T<Us...>, Vs...> { 
    constexpr static int n = sizeof...(Us) + S<Vs...>::n; 
}; 

template<typename...> struct D {}; 

#include <iostream> 
int main() { 
    std::cout << S<D<int, int, int>, D<int, int>, D<int>>::n << '\n'; // prints 6 
} 
+0

Danke, deine Antwort öffne meine Augen. Ich habe meine letzte Lösung für meine Frage gefunden. Hoffe das hilft jemand anderem. – Klaus

1

So:

template < template <typename...> class ...T > 
class F 
{ 
}; 
int main() 
{ 
    F< D, D > f; 
} 

Also, was F erwartet eine variadische Template-Klasse, die eine andere variadische Template-Klasse nimmt, wie es Argument ist.

Sie können die Argumente der Argumente des Template-Klassenarguments nicht erweitern. Wenn Sie die Vorlagenklasse spezialisieren, die Sie als Argument übergeben, erhalten Sie die spezialisierte Version. Diese

:

F< D< int, float>, D< int>, D <float, float, float> > f; 

nicht funktioniert, da F variadische Template-Klasse erwartet, unter variadische Template-Klassen als Typen und D< int, float> ist keine Vorlage mehr (es ist eine konkrete Klasse).

+0

@Klaus Du hast geschrieben: 'keine Chance, in A einzureichen!'. Sie können in A diesen 'typedef A type' machen und ihn in B als' typeName A :: type' verwenden, aber Sie können das nicht in einer variadischen Vorlage tun (dies ist nicht möglich: 'typedef typename ... types') –

+0

Scheint so zu sein, dass ich total falsch liege und variadische Vorlagenvorlagen nicht die Lösung sind. Gibt es eine andere Möglichkeit, die erforderliche Funktionalität zu erhalten? Es ist leicht eine Liste zu bekommen, die durch Spezialisierung erweitert werden kann. Ich hoffe immer noch, dass es auch mit einer Liste von Listen einen Weg zu solchen Dingen gibt. Jeder Hinweis ist willkommen! Kannst du mir ein funktionierendes Beispiel dafür geben, was du in deinem letzten Kommentar meinst? – Klaus

Verwandte Themen