2011-07-06 8 views
10

sé la respuesta a la frecuencia-pedido How do I specify a pointer to an overloaded function?: Ya sea con la tarea o con un yeso, y cada otro tutorial C++ las mayúsculas de una cadena como esta (más o menos static_cast):¿Cómo uso las funciones sobrecargadas con argumentos predeterminados en los algoritmos?

transform(in.begin(), in.end(), back_inserter(out), (int(*)(int)) std::toupper); 

O como este :

int (*fp)(int) = std::toupper; 
transform(in.begin(), in.end(), back_inserter(out), fp); 

que selecciona cuidadosamente la sobrecarga de <cctype>std::toupper.

Pero esto plantea la pregunta: ¿Cómo puedo seleccionar la sobrecarga <locale> de una manera similar?

char (*fp2)(char, const std::locale&) = std::toupper; 
transform(in.begin(), in.end(), back_inserter(out), fp2); 
// error: too few arguments to function 

O, de manera más práctica, considere la posibilidad de alguien que intenta utilizar el C++ 11 std::stoi en un algoritmo para convertir un vector de cadenas a un vector de enteros: stoi tiene dos sobrecargas (string/wstring), cada uno toma dos argumentos predeterminados adicionales.

Suponiendo que no quiero explicitly bind todos esos valores predeterminados, creo que es imposible hacer esto sin envolver dicha llamada en una función auxiliar o lambda. ¿Existe una envoltura de impulso o magia de TMP para hacerlo de una manera completamente genérica? ¿Se puede escribir un envoltorio como call_as<char(char)>(fp2) o, más probablemente, call_as<int(const std::string&)>(std::stoi)?

+3

Puede usted sólo tiene que utilizar una lambda en su comando 'transform'? Más fácil y más limpio. –

+0

Escribí y borré un comentario acerca de que 'bind' ya era la envoltura que estabas buscando. Luego se me ocurrió que tendrías que proporcionar los valores predeterminados para enlazar, y así redefinirlos. –

+0

Es mejor obtener el algoritmo correcto antes de pensar cómo ofuscar el código a través de las plantillas. Entonces, comienza con el algoritmo. La llamada 'std :: toupper' produce un Comportamiento no definido si existe un argumento negativo, excepto el valor 'EOF'. –

Respuesta

5

Es gracioso, estaba haciendo algo similar. La mejor manera que encontré para hacerlo fue usando lambdas de la siguiente manera, porque de lo contrario, tienes que usar un typedef para obtener la sobrecarga correcta y un std :: bind para deshacerte de la configuración regional, o no usar la configuración regional. Sin embargo, esto funciona mucho más limpia:

static const std::locale loc; 
transform(in.begin(), in.end(), back_inserter(out), [&loc](char c) { 
    return std::toupper(c, loc); 
}); 

utilizo la estática para ahorrar el esfuerzo de reasignación de cada vez.

O usted podría conseguir un typedef y hacer:

std::bind((LocaleCompare)std::toupper, std::placeholders::_1, loc); // UGLY! 
0

Puede crear un typedef de ese tipo de puntero functon y luego ejecutar la función.

typedef char (*LocaleToUpper)(char, const std::locale&) ; 
char (*fp2)(char, const std::locale&) = (LocaleToUpper)toupper; 
Cuestiones relacionadas