Sintassi C ++ per la specializzazione esplicita di una funzione template in una class template?

Ho un codice che funziona in VC9 (Microsoft Visual C ++ 2008 SP1) ma non in GCC 4.2 (su Mac):

struct tag {}; template struct C { template void f( T ); // declaration only template inline void f( T ) {} // ERROR: explicit specialization in }; // non-namespace scope 'structC' 

Capisco che GCC vorrebbe che trasferissi la mia esplicita specializzazione al di fuori della class, ma non riesco a capire la syntax. Qualche idea?

 // the following is not correct syntax, what is? template template inline void C::f( T ) {} 

Non è ansible specializzare una funzione membro senza specializzarsi esplicitamente nella class contenente.
Tuttavia, ciò che puoi fare è inoltrare le chiamate a una funzione membro di un tipo parzialmente specializzato:

 template struct helper { static void f(T); }; template struct helper { static void f(T) {} }; template struct C { // ... template void foo(T t) { helper::f(t); } }; 

GCC è chiaro, qui. MSVC ha un’estensione non standard che consente la specializzazione in class. Lo standard, tuttavia, dice:

14.7.3.2:
2. Una specializzazione esplicita deve essere dichiarata nello spazio dei nomi di cui il modello è un membro, oppure, per i modelli di membri, nello spazio dei nomi di cui la class di inclusione o il modello di class che racchiude è un membro. Una specializzazione esplicita di una funzione membro, di una class membro o di un membro di dati statici di un modello di class deve essere dichiarata nello spazio dei nomi di cui il modello di class è membro.

Inoltre, non è ansible specializzare parzialmente una funzione. (Anche se non sono sicuro dei dettagli nel tuo caso, quello sarebbe il colpo finale.)

Potresti fare questo:

 #include  struct true_type {}; struct false_type {}; template  struct is_same : false_type { static const bool value = false; }; template  struct is_same : true_type { static const bool value = true; }; struct tag1 {}; struct tag2 {}; template< typename T > struct C { typedef T t_type; template< typename Tag > void foo( t_type pX) { foo_detail( pX, is_same() ); } private: void foo_detail( t_type, const true_type& ) { std::cout << "In tag1 version." << std::endl; } void foo_detail( t_type, const false_type& ) { std::cout << "In not tag1 version." << std::endl; } }; int main(void) { C c; c.foo(int()); c.foo(int()); c.foo(int()); } 

Anche se questo è un po ‘brutto.

Prova questo:

 template <> template inline void C :: foo(T) {} 

So che questo potrebbe non soddisfarti, ma non credo che potresti non avere una specializzazione racchiusa in una struttura non esplicitamente specializzata.

 template<> template<> inline void C< tag1 >::foo< tag2 >( t_type ) {}