2009-06-02 19 views
30

Qual è la ragione per la seconda parentesi <> nel seguente modello di funzione:Funzione formato del modello di specializzazione

template<> void doh::operator()<>(int i) 

Ciò è avvenuto in SO question in cui è stato suggerito che ci sono parentesi mancanti dopo operator(), però ho potuto non trovare la spiegazione.

ho capito il significato, se si trattava di un tipo di specializzazione (pieno di specializzazione) del modulo:

template< typename A > struct AA {}; 
template<> struct AA<int> {};   // hope this is correct, specialize for int 

Tuttavia per i modelli di funzione:

template< typename A > void f(A); 
template< typename A > void f(A*); // overload of the above for pointers 
template<> void f<int>(int);   // full specialization for int 

Da dove viene questo rientrano in questa scenarion ?:

template<> void doh::operator()<>(bool b) {} 

Esempio di codice che sembra funzionare e non fornisce alcun wa rnings/errore (gcc 3.3.3 utilizzato):

#include <iostream> 
using namespace std; 

struct doh 
{ 
    void operator()(bool b) 
    { 
     cout << "operator()(bool b)" << endl; 
    } 

    template< typename T > void operator()(T t) 
    { 
     cout << "template <typename T> void operator()(T t)" << endl; 
    } 
}; 
// note can't specialize inline, have to declare outside of the class body 
template<> void doh::operator()(int i) 
{ 
    cout << "template <> void operator()(int i)" << endl; 
} 
template<> void doh::operator()(bool b) 
{ 
    cout << "template <> void operator()(bool b)" << endl; 
} 

int main() 
{ 
    doh d; 
    int i; 
    bool b; 
    d(b); 
    d(i); 
} 

uscita:

operator()(bool b) 
template <> void operator()(int i) 
+0

la sintassi precedente della doppia parentesi è molto dispari. Normalmente ho visto l'operatore (bool b), ma come funziona operator() (bool b)? A cosa serve il primo empty()? – Jimm

+1

@Jimm il nome del metodo è 'operator()' e prende un parametro 'bool b' ... è l'operatore di chiamata di funzione. Vedi 'main' nel mio esempio di codice,' d (b) ' – stefanB

risposta

31

Ho guardato in su, e ha scoperto che è specificato da 14.5.2/2:

A local class shall not have member templates. Access control rules (clause 11) apply to member template names. A destructor shall not be a member template. A normal (non-template) member function with a given name and type and a member function template of the same name, which could be used to generate a specialization of the same type, can both be declared in a class. When both exist, a use of that name and type refers to the non-template member unless an explicit template argument list is supplied.

E fornisce un esempio:

template <class T> struct A { 
    void f(int); 
    template <class T2> void f(T2); 
}; 

template <> void A<int>::f(int) { } // non-template member 
template <> template <> void A<int>::f<>(int) { } // template member 

int main() 
{ 
    A<char> ac; 
    ac.f(1); //non-template 
    ac.f(’c’); //template 
    ac.f<>(1); //template 
} 

si noti che in S termini standard, specialization si riferisce alla funzione che si scrive utilizzando una specializzazione esplicita e alla funzione generata mediante l'istanziazione, nel qual caso abbiamo a che fare con una specializzazione generata. specialization non si riferisce solo alle funzioni create utilizzando la specializzazione esplicita di un modello, per cui viene spesso utilizzata solo.

Conclusione: GCC sbaglia. Comeau, con il quale ho anche provato il codice, ottiene di destra ed emette una diagnosi:

"ComeauTest.c" , line 16: error: "void doh::operator()(bool)" is not an entity that can be explicitly specialized template<> void doh::operator()(bool i)

Nota che non si lamenta la specializzazione del modello per int (solo per bool), dal momento che doesn' t fare riferimento allo stesso nome e tipo: il tipo di funzione che avrebbe la specializzazione è void(int), che è distinto dal tipo di funzione della funzione membro non modello, che è void(bool).

+0

Quindi se seguo correttamente il 'membro template' sopra è un membro di template in" specializzazione di struct A for int ". Ha senso ora, quindi chiamare ac.f() farà la propria risoluzione del template basata sul parametro o sull'elenco dei parametri del template esplicito (qualunque sia il nome corretto). – stefanB

+1

sì, la specializzazione esplicita che abbiamo fornito per f è per la specializzazione della struct A per int. il modello base generale f esiste per tutte le specializzazioni di A.Ecco perché possiamo anche chiamarlo su un A , come fa naturalmente in main (ma non userà la nostra specializzazione esplicita, dato che era solo per A :: f !). Sì, ac.f (roba) ha una sua risoluzione, anzi. Qui, consultare 14.8.1/2 ("Argomenti di template finali che possono essere dedotti ..."). Spero che questo aiuti :) –

+0

Sì, grazie per la ricerca :) – stefanB

Problemi correlati