Frage

, stieß ich auf ein anderes Problem.

Unter der Annahme der folgenden Template-Klasse:

template < typename T >
struct foo 
{
    //default implementation
};

ist es möglich, sie teilweise für instantiations variadische Vorlage zu spezialisieren wie folgt aus:

template < template < typename ... > class T, typename ...Args >
struct foo< T< Args... > >
{
    //specialized implementation
};

Damit foo< int > auf die Default-Implementierung und foo< std::tuple< int, char > > auf die spezialisierte Implementierung entspricht.

Allerdings werden die Dinge noch komplizierter, wenn mehrere Template-Parameter verwenden. Zum Beispiel, wenn wir die folgenden Template-Klasse haben

template < typename T, typename U >
struct bar {};

und wir wollen es teilweise spezialisieren, wie wir für foo haben, können wir dies nicht tun

template < template < typename ... > class T, typename ...TArgs,
           template < typename ... > class U, typename ...UArgs >
struct bar< T< TArgs... >, U< UArgs... > > {};

//This would correspond to the specialized version with
//T=std::tuple,
//TArgs=int,char
//U=std::tuple,
//UArgs=float
bar< std::tuple< int, char >, std::tuple< float > > b;

Ja, wenn ich richtig bin, können wir nur eine Template-Parameter Pack und es muss am Ende der Parameterliste positioniert werden. Ich verstehe, warum dies in Vorlage Erklärungen obligatorisch ist, aber für bestimmte Teil Template-Spezialisierung (wie im Beispiel oben), sollte dies kein Problem sein.

Ist es möglich, partielle Template-Spezialisierung mit mehrer Template-Parameter-Pack zu erreichen?


Bearbeiten : Jetzt fühle ich mich dumm ... der Code, den ich oben compiles gab perfekt (zumindest mit gcc 4.5). Der Compiler-Fehler hatte ich war nicht wegen mehrerer Parameter Packs, sondern wegen ihrer Verwendung als Elementfunktionen Parameter. In der Teil Spezialisierung der bar habe ich versucht, eine Elementfunktion zu definieren, die beide TArgs und UArgs Parameter verwendet:

template < template < typename ... > class T, typename ...TArgs, 
           template < typename ... > class U, typename ...UArgs >
struct bar< T< TArgs... >, U< UArgs... > >
{
    void method( TArgs... targs, UArgs... uargs ) //compile error here
    {
    }
};

Auf der Mitgliedsfunktionsdeklaration, gcc gibt mir den Fehler

Parameter Packungen am Ende der Parameterliste sein muss.

Soweit ich das beurteilen kann, sollte der Compiler der Lage sein, die richtige Member-Funktion für eine bestimmte Vorlage Instanziierung zu definieren, z.B. bar< std::tuple< int, char >, std::tuple< float > > sollte eine Elementfunktion void method( int, char, float ) enthalten. Mache ich etwas falsch? Oder versuche ich, etwas zu tun, was nicht möglich ist? Wenn ja, gibt es einen guten Grund, warum dies nicht möglich ist?

War es hilfreich?

Lösung

Wahrscheinlich wird diese Antwort nicht direkt löschen Ihre Frage, aber der folgende Code kompiliert auf ideone (gcc-4.5.1), wenn ich getestet.

#include <cstdio>
#include <tuple>

template< class, class > struct S {
  S() { puts("primary"); }
};

template<
  template< class... > class T, class...TArgs
, template< class... > class U, class...UArgs
>
struct S< T< TArgs... >, U< UArgs... > > {
  S() { puts("specialized"); }
};

int main()
{
  S< int, int >  p;                                       // "primary"
  S< std::tuple< int, char >, std::tuple< float > >  s;   // "specialised"
}

Ich bin nicht sicher, ob dieser Code ist streng konform, aber soweit ich das N3225 14.5.3 las, konnte ich nicht die Aussage finden, die erwähnt dass Template-Parameter Pack hat die letzten Template-Parameter sein.

Edit:
Ich las N3225 und fand die folgenden Aussagen:

8.3.5 / 4 Wenn die Parameter-Deklaration-Klausel endet mit einem Auslassungszeichen oder einem Funktionsparametersatz (14.5.3), der Anzahl der Argumente ist gleich zu oder größer als die Anzahl der Parameter, die eine Standard haben keine Argument und ist nicht funktionieren Parameter-Pack.

14.8.2.5/10 [Hinweis: Ein Funktionsparameter Paket kann nur auf dem auftreten Ende eines Parameter-declarationlist (8.3.5). -Ende Anmerkung]

So, wie Sie erwähnten, Funktionsparameter Pack hat der letzte Parameter sein leider.
Eine nicht-Template Elementfunktion einer Klassenschablone ist eine gewöhnliche Funktion für diese Klasse, wenn es instanziiert wird (vollständig spezialisiert). So wünsche ich, dass der Code in dieser Frage logisch kompiliert werden, wie ein Sonderfall dar.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top