Consideremos el siguiente ejemplo:¿Cómo puedo escribir una plantilla de función para todos los tipos con un rasgo de tipo particular?
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 clase Scanner
se utiliza para extraer tokens de alguna fuente. El código anterior funciona bien, pero falla cuando trato de get
otros tipos integrales como char
o unsigned int
. El código para leer estos tipos es exactamente el mismo que el código para leer un int
. Podría duplicar el código para todos los otros tipos integrales que quisiera leer, pero prefiero definir una plantilla de función para todos los tipos integrales.
He intentado lo siguiente:
struct Scanner
{
template <typename T>
typename enable_if<boost::is_integral<T>, T>::type get();
};
que funciona como un encanto, pero no estoy seguro cómo conseguir Scanner::get<string>()
a funcionar de nuevo. Entonces, ¿cómo puedo escribir código para poder hacer scanner.get<string>()
y scanner.get<any integral type>()
y tener una definición única para leer todos los tipos integrales?
Actualización: pregunta de bonificación: ¿Qué sucede si quiero aceptar más de un rango de clases en función de algunos rasgos? Por ejemplo: cómo abordar este problema si quiero tener tres funciones get
que acepten (i) tipos enteros (ii) cadenas de tipos de coma flotante (iii), respectivamente.
Quiero decir que probablemente puedas usar 'boost :: mpl :: and_' y' boost :: mpl :: or_' para combinar los argumentos en 'disable_if'. +1, no obstante :) :) –
También podría usar 'ice_and' y' ice_or' de la biblioteca de Boost. –