Betrachten Sie das folgende Beispiel:Wie kann ich eine Funktionsvorlage für alle Typen mit einem bestimmten Typmerkmal schreiben?
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>();
}
Die Scanner
Klasse verwendet wird Token von einer Quelle zu extrahieren. Der obige Code funktioniert gut, aber schlägt fehl, wenn ich versuche, andere integrale Typen wie oder unsigned int
zu get
. Der Code zum Lesen dieser Typen entspricht genau dem Code zum Lesen einer int
. Ich könnte einfach den Code für alle anderen integralen Typen kopieren, die ich gerne lesen würde, aber ich würde lieber eine Funktionsvorlage für alle integralen Typen definieren.
Ich habe versucht, die folgenden:
struct Scanner
{
template <typename T>
typename enable_if<boost::is_integral<T>, T>::type get();
};
Welche funktioniert wie ein Charme, aber ich bin nicht sicher, wie Scanner::get<string>()
zu bekommen wieder zu funktionieren. Also, wie kann ich Code schreiben, so dass ich scanner.get<string>()
und scanner.get<any integral type>()
tun kann und eine einzige Definition haben, um alle integralen Typen zu lesen?
Update: Bonus Frage: Was ist, wenn ich mehr als eine Reihe von Klassen basierend auf einigen Merkmalen akzeptieren möchte? Zum Beispiel: Wie sollte ich dieses Problem angehen, wenn ich drei get
Funktionen haben möchte, die (i) integrale Typen (ii) Fließkommatypen (iii) Zeichenketten akzeptieren.
Ich würde bemerken, dass Sie wahrscheinlich die 'boost :: mpl :: und_' und 'boost :: mpl :: or_' verwenden könnten, um die Argumente in 'disable_if' zu kombinieren. +1 nichtsdestotrotz :) –
Sie können auch 'ice_and' und' ice_or' aus der Boost-Bibliothek verwenden. –