Continuando con my journey into the world of variadic templates, ho riscontrato un altro problema.Specializzazione modello parziale con più pacchetti di parametri modello
Assumendo 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>
corrisponderà alla implementazione predefinita e foo< std::tuple< int, char > >
all'attuazione specializzata.
Tuttavia, le cose diventano più complicate quando si utilizzano diversi parametri del modello. Per esempio, se abbiamo la seguente classe template
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;
Anzi, se non sbaglio, possiamo solo avere un pacchetto di parametri template e deve essere posizionato alla fine dell'elenco dei parametri. Capisco perché questo sia obbligatorio nelle dichiarazioni dei modelli, ma per alcune specializzazioni di template parziali (come nell'esempio sopra), questo non dovrebbe essere un problema.
È possibile ottenere una specializzazione del modello parziale con più pacchetti di parametri modello?
Edit: Ora mi sento stupido ... il codice che ho dato sopra compila perfettamente (almeno con gcc 4.5). L'errore di compilazione che avevo non era dovuto a più pacchetti di parametri, ma a causa del loro utilizzo come parametri delle funzioni membro. Nella specializzazione parziale di bar
, ho cercato di definire una funzione membro che prende sia TArgs
e UArgs
parametri:
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
{
}
};
Nella dichiarazione funzione membro, gcc mi dà l'errore
parametri pacchi devono essere alla fine della lista dei parametri.
Per quanto posso dire, il compilatore dovrebbe essere in grado di definire la funzione membro corretta per una data istanziazione di modello, ad es. 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?
Neat, non sapevo che potresti specializzare/specificare (parte) gli elementi di un elenco di modelli come modelli stessi. – JAB