Domanda

il mio viaggio nel mondo dei modelli variadic , ho incontrato un altro problema.

Supponendo la seguente classe template:

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

è possibile specializzarsi in parte per istanze di template variadic come questo:

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

Con questo, foo< int > sarà conforme a l'implementazione di default e foo< std::tuple< int, char > > all'attuazione specializzata.

Tuttavia, le cose diventano più complicate quando si usano diversi parametri di modello. Per esempio, se abbiamo la classe template seguente

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

e vogliamo specializzarsi in parte come abbiamo fatto per foo, non possiamo fare

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;

In effetti, se non sbaglio, possiamo avere solo parametro pacchetto un modello e che devono essere posizionati alla fine della lista dei parametri. Capisco perché questo è obbligatorio nelle dichiarazioni di template, ma di certo modello di specializzazione parziale (come nell'esempio sopra), questo non dovrebbe essere un problema.

E 'possibile raggiungere il modello di specializzazione parziale con confezioni multiple parametro di modello?


Modifica : Ora mi sento stupido ... il codice che ho dato sopra compilazione perfettamente (almeno con gcc 4.5). L'errore di compilazione avevo non era causa di confezioni multiple di parametri, ma a causa del loro uso come parametri funzioni membro. Nella specializzazione parziale di bar, ho cercato di definire una funzione membro che prende entrambi i parametri TArgs e UArgs:

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
    {
    }
};

Sulla dichiarazione di funzione membro, gcc mi dà l'errore

Parametri pacchi devono essere alla fine dell'elenco di parametri.

Per quanto posso dire, il compilatore dovrebbe essere in grado di definire la funzione di membro corretto per un determinato modello di istanza, ad esempio, bar< std::tuple< int, char >, std::tuple< float > > dovrebbe contenere una funzione membro void method( int, char, float ). Sto facendo qualcosa di sbagliato? O sto cercando di fare qualcosa che non è possibile? Se è così, c'è una buona ragione per cui questo non è possibile?

È stato utile?

Soluzione

Probabilmente questa risposta non sarà chiaro direttamente alla tua domanda, ma il seguente codice compilato sulla Ideone (gcc-4.5.1) quando ho provato.

#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"
}

Non sono sicuro che questo codice è strettamente conforme, ma per quanto ho letto N3225 14.5.3, non riuscivo a trovare la dichiarazione che menziona tale parametro Template Pack deve essere l'ultimo parametro di template.

Modifica:
Ho riletto N3225 e ho trovato le seguenti dichiarazioni:

8.3.5 / 4 Se il parametro-dichiarazione-clausola termina con un'ellissi o parametro funzione pack (14.5.3), la numero di argomenti è pari a o maggiore del numero di parametri che non hanno un valore predefinito argomento e non sono funzione confezioni parametri.

14.8.2.5/10 [Nota: Un parametro funzione pack può avvenire solo al Dopo una parametro-declarationlist (8.3.5). -fine Nota]

Quindi, come lei ha ricordato, il parametro funzione pack deve essere l'ultimo parametro purtroppo.
Una funzione membro non-modello di un modello di classe è una funzione ordinaria per quella classe quando viene creata un'istanza (completamente specializzata). Così mi auguro che il codice in questione può essere compilato logicamente, come caso speciale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top