Funzione formato del modello di specializzazione
-
06-09-2019 - |
Domanda
Qual è la ragione per la seconda parentesi <> nel seguente modello di funzione:
template<> void doh::operator()<>(int i)
Questo è venuto in domanda SO in cui è stato suggerito che ci sono staffe dispersi dopo operator()
, tuttavia, non sono riuscito a 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) {}
il codice di esempio che sembra funzionare e non dà alcun avviso / errore (3.3.3 gcc usato):
#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);
}
Output:
operator()(bool b)
template <> void operator()(int i)
Soluzione
Ho guardato in su, e ha scoperto che è specificato da 14.5.2 / 2:
Una classe locale non deve avere modelli di membro. Regole di controllo dell'accesso (clausola 11) si applicano ai nomi dei modelli utente. Un distruttore non deve essere un modello di membro. Un normale (non-template) funzione membro con un dato nome e il tipo e modello di funzione membro dello stesso nome, che potrebbe essere utilizzato per generare una specializzazione dello stesso tipo, può sia essere dichiarato in una classe. Quando entrambi esistono, un uso di tale nome e il tipo si riferisce al membro non modello di meno che un elenco di modelli argomento esplicito viene fornito.
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 termini standard, specialization
si riferisce alla funzione che si scrive con una specializzazione esplicita e per la funzione generata utilizzando esemplificazione, in questo caso abbiamo a che fare con una specializzazione generato. specialization
non si riferisce solo alle funzioni create utilizzando esplicitamente specializzata un modello, per il quale è spesso utilizzato solo.
Conclusione: GCC sbaglia. Comeau, con il quale ho anche provato il codice, ottiene di destra ed emette una diagnosi:
"ComeauTest.c"
, linea 16: errore:"void doh::operator()(bool)"
non è un'entità che può essere esplicitamente specializzatatemplate<> void doh::operator()(bool i)
Si noti che non si lamenta la specializzazione del modello per int
(solo per bool
), dal momento che non si riferisce allo stesso nome e Tipo: il tipo di funzione che la specializzazione avrebbe avere è void(int)
, che è distinta dalla funzione tipo di funzione membro non-template, che è void(bool)
.