2010-04-30 8 views
6

C'è una differenza tra i seguenti approcci?Sintassi per modelli di funzioni specializzate

// approach 1 
namespace std 
{ 
    template<> 
    void swap<Foo>(Foo& x, Foo& y) // note the <Foo> 
    { 
     x.swap(y); 
    } 
} 

// approach 2 
namespace std 
{ 
    template<> 
    void swap(Foo& x, Foo& y) 
    { 
     x.swap(y); 
    } 
} 

ho stumpled su questo quando ho provato a specializzarsi swap per il mio tipo di stringa e ho notato che swap<::string> non funziona, ma per un motivo completamente diverso :)

+0

E che tipo ha il nome ':: string'? – Potatoswatter

+0

Il mio tipo di stringa giocattolo nello spazio dei nomi globale. – fredoverflow

risposta

8

sì, c'è. Ma non in quel particolare esempio. Se il parametro non viene dedotta, può fare la differenza

template<typename T> void f(typename T::type t); 

Non si può specializzare che senza <type> perché non può dedurre cosa T da lista dei parametri.

struct MyType { typedef int type; }; 

// needs <MyType> 
template<> void f<MyType>(int t) { } 

Naturalmente nel tuo caso, è il digramma <: che ha senso la stessa [ causando il problema. Metti uno spazio come <   ::string> per evitare il problema.

+0

+1 Grazie per la spiegazione! E questa roba di digraph è così divertente :) – fredoverflow

+0

Sai cosa porta effettivamente a quella sintassi permessa nello standard? Al momento non lo vedo. –

+0

@ gf intendi la sintassi 'f <..>'? È un id-template, che è un'espressione id, che è un id-dichiaratore. –

0

Inoltre, non è necessario specializzarsi in questo caso, basta sovraccaricare ed essere felici.

namespace std 
{ 
    void swap(Foo& x, Foo& y) 
    { 
     x.swap(y); 
    } 
} 
+0

Se ti piace il comportamento non definito, allora sì :) Non sei autorizzato a sovraccaricare nello spazio dei nomi 'std'. – fredoverflow

Problemi correlati