2011-12-16 12 views
16

Lo que me gustaría hacer es algo como esto:¿La mejor alternativa a un typedef para una plantilla de función?

template <class DataType> 
DataType myFunc(DataType in) 
{ 
    ... 
} 

typedef myFunc<int> myFunc_i; 

myFunc_i(37); 

... sin embargo, typedefs no se pueden utilizar para funciones como esto en C++. Lo que me preguntaba es ... ¿cuáles son las alternativas preferidas por las personas en este caso? Los únicos que se me ocurren son:

1) Sólo tratar con él, y utilizar siempre myFunc sintaxis 2) crear manualmente una función de contenedor, es decir

inline int myFunc_i(int in) 
{ 
    return myFunc<int>(in); 
} 

Esto funcionaría, pero tendría el desventaja de requerir mantenimiento adicional, y la posibilidad de que se desincronice (es decir, si cambia la firma de la función para myFunc).

¿Pensamientos?

+1

No entiendo, ¿por qué no llamar a la especialización directamente myFunc '(37); '? –

Respuesta

1

Uso decltype:

template <class DataType> 
DataType myFunc(DataType in) 
{ 
    ... 
} 

using myFunc_i = decltype(myFunc<int>(0)); 

myFunc_i(37); 
+0

¡Realmente no funciona! – Silencer

4

Código Ejemplo:

#include <iostream> 


template <typename T> 
T sqr(T a){ 
    return a*a; 
} 

auto s = sqr<int>; 
int main() { 

    std::cout<<s(3.9); 
    return 0; 
} 

impresiones 9, que significa que utiliza la función int
auto requiere C++ 0x, es posible utilizar nombre de tipo real en lugar, pero es feo y usted necesitará cambiar de verificación de firma también. Además, este código, puede rechazar su compilador a inline esta función

  • En cuanto a mí, a menudo es mejor utilizar el nombre completo con <>

  • En su caso no es necesario utilizar <> porque myFunc es suficiente (DataType pueden ya ha recibido tipo de argumento)

+0

Tu ejemplo no compila para mí ... por "requries C++" ¿quisiste decir C++ 0x o microsoft? –

+0

@PaulMolodowitch, me refiero a C++ 0x, de cource, perdón por descuido – RiaD

14

Prueba esto:

typedef int (*myFunc_i_type)(int); 
myFunc_i_type const myFunc_i = &myFunc<int>; 

Esto desencadenará un error de compilación si la firma de myFunc cambia alguna vez. Hacerlo const también prohíbe la reasignación. Los punteros de función también se pueden llamar como cualquier función normal: myFunc_i(5).

Si no desea que un error de compilación sino que tienen que actualice a sí mismo, utilizar auto (de nuevo con const):

auto const myFunc_i = &myFunc<int>; 
5

Algunos pueden estar en desacuerdo, algunos pueden sacudir sus rodillas contra esto, pero considera esto opción:

#define myFunc_i myFunc<int> 

En lo que respecta a las macros, esta es bastante segura; el único peligro es que alguien pueda redefinirlo o definirlo más tarde.

Aparte de eso, tiene todas las ventajas de auto const myFunc = myFunc<int>;. Si quiere auto pero no quiere usar las características de C++ 0x, esta es una forma más portátil de lograr el mismo efecto.

+0

Eso es ... honestamente, uno de los mejores usos que he visto para las macros de preprocesador en C++. También puede funcionar bien con las macros variadas C99/C++ 11, por ejemplo, si desea poder especificar explícitamente los parámetros de la plantilla de función sin tener que escribirlos cada vez. Por ejemplo, '#define myFunc_allSameType (a, ...) myFunc (a, __VA_ARGS __)' en MSVC o '#define myFunc_allSameType (a, ...) myFunc (a, ## __ VA_ARGS __)' en GCC. No siempre es útil, pero es útil en los casos en los que hay muchos parámetros de plantilla, y todos se conocen previamente o se determinan a partir de argumentos. –

2

Haría una pequeña mejora sobre la respuesta de Xeo.

En lugar de utilizar:

auto const myFunc_i = &myFunc<int>; 

me gustaría utilizar

constexpr auto myFunc_i = &myFunc<int>; 
Cuestiones relacionadas