2012-09-26 19 views
5

Eso debería ser trivial de implementar, algo así como¿Hay una función estándar que solo devuelve su parámetro?

template<typename T> 
T & as_is(T & t) { return t; } 

Aún así, me gustaría no tener que escribirla (:

No he encontrado una cosa así en www.cplusplus.com

. Para aquellos que preguntarán "¿qué estás tratando de hacer?", Aquí está la cosa. Tengo una clase que construye tablas ascii, con un buen relleno y todo. Me ahorraré los detalles. Lo importante es que almacena cadenas (así que es capaz de calcular cuánto rellenar). Quiero implementar una función de clasificación y poder decirle a la clase t o usa la columna como un cierto tipo. Si quiero ordenar por una columna de ints (que, de nuevo, son cadenas internas), pasaría atoi. Si selecciono cadenas, quiero pasar as_is o el equivalente stl, si corresponde.

+4

Tal vez 'std :: forward ' cumple esos requisitos? –

+1

@Kerrek: Es una buena opción, aunque requiere que deletree los argumentos de la plantilla. – Xeo

Respuesta

2

No se puede pasar una plantilla como si fuera una función, por lo que ni std :: forward ni su hipotética función no std :: identity funcionarán como están (por así decirlo). Que había necesidad de establecer explícitamente el tipo de destino de la transformada:

table.SortColumnUsing(3, nonstd::identity<std::string>); 

Eso parece un poco feo para mí, porque el tipo en la especialización de plantilla es una característica de la implementación interna de la mesa, en lugar de tener nada que ver con el tipo en el que espero que la tabla se serialice para fines de clasificación. O tal vez no almacene realmente las columnas como std :: string.

¿Cómo funciona atoi como un descriptor de tipo? atoi espera un char *, no un std :: string, y no creo que puedas convertir implícitamente int(const char*) en int(const std::string&). Incluso si pudieras hacer eso, qué tipo usas, que puede almacenar un int(const std::string&) y un Banana(const std string&). Tal vez no entiendo completamente el contexto de su pregunta, o como alternativa, tengo algunos trucos de C++ en la manga que me encantaría aprender.

Mi inclinación sería pasar una función de comparación en lugar de una función de conversión. Eso daría como resultado un único tipo de función constante, tal vez bool(const std::string&, const std::string&). Eso también podría hacer que sea más sencillo de implementar, por ejemplo. Comparación de cadenas insensible a mayúsculas y minúsculas para determinadas columnas, u otros hacks de clasificación convenientes para UI (como colocar carpetas en la parte superior de la lista: primero compruebe si solo una de las cadenas tiene un final /, de lo contrario use una comparación estándar). Sin embargo, eso no soluciona realmente el problema de la especialización; para el caso std::string, aún así termina con std::less<std::string> (que al menos existe.)

No es una gran respuesta, lo sé ... pero fue demasiado tiempo para un comentario.

+1

Esta es una buena respuesta, ya que va después de la causa, no del problema. Pasar una función de conversión para ordenar en "orden integral" suena mal tal como está, entonces +1 al sugerir una función de comparación. – Xeo

+0

En realidad estoy pasando una función de comparación a la función de clasificación actual. Quiero (ed) deshacerme de él debido a la verbosidad de la construcción. Dicho esto, me olvidé de que todavía tengo que '.c_str()' las cadenas en el 'atoi' del funtor, lo que evitaría pasarlo como está a la función de clasificación, rompiendo así el ejemplo. – Gabriel

3

¿Por qué no sobrecargar la función y no pasar nada?

Por cierto, si está trabajando con MSVC, tienen la plantilla de clase identity, que tiene una operator() sobrecargada que devuelve la entrada. Entonces, en teoría, podría pasar std::identity<std::string>(), pero yo diría que solo construya su propia función identity.

+0

Interesante. Parece que la identidad no es específica de MS: http://www.sgi.com/tech/stl/identity.html http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-api-4.5/a00497.html – Gabriel

+0

La sobrecarga significaría duplicar código.Para evitar la duplicación, la sobrecarga sin param llamaría a la versión con param, dando identidad. Esto proporcionaría métodos de conveniencia, agregando complejidad sin agregar ninguna característica. – Gabriel

+2

@Gabriel estaba en un borrador anterior del último estándar pero se eliminó. No lo encontrará en GCC 4.6. –

Cuestiones relacionadas