consideri il seguente esempio:Come posso scrivere un modello di funzione per tutti i tipi con un particolare tipo di tratto?
struct Scanner
{
template <typename T>
T get();
};
template <>
string Scanner::get()
{
return string("string");
}
template <>
int Scanner::get()
{
return 10;
}
int main()
{
Scanner scanner;
string s = scanner.get<string>();
int i = scanner.get<int>();
}
La classe Scanner
viene utilizzato per estrarre i token da qualche fonte. Il codice precedente funziona correttamente, ma non riesce quando provo a get
altri tipi integrali come uno char
o uno unsigned int
. Il codice per leggere questi tipi è esattamente lo stesso del codice per leggere un int
. Potrei semplicemente duplicare il codice per tutti gli altri tipi interi che vorrei leggere, ma preferirei definire un modello di funzione per tutti i tipi interi.
ho provato la seguente:
struct Scanner
{
template <typename T>
typename enable_if<boost::is_integral<T>, T>::type get();
};
che funziona come un fascino, ma non sono sicuro come ottenere Scanner::get<string>()
a funzionare di nuovo. Quindi, come posso scrivere il codice in modo che possa fare scanner.get<string>()
e scanner.get<any integral type>()
e avere una singola definizione per leggere tutti i tipi interi?
Aggiornamento: domanda bonus: Cosa succede se desidero accettare più di una gamma di classi basate su alcuni tratti? Ad esempio: come dovrei affrontare questo problema se voglio avere tre funzioni get
che accettano (i) tipi interi (ii) tipi a virgola mobile (iii) stringhe, rispettivamente.
Vorrei sottolineare che potreste probabilmente usare 'boost :: mpl :: and_' e' boost :: mpl :: or_' per combinare gli argomenti in 'disable_if'. +1 comunque :) –
Puoi anche usare 'ice_and' e' ice_or' dalla libreria Boost. –