Es fácil crear un nuevo nombre para un tipo, una variable o un espacio de nombres. Pero, ¿cómo asigno un nuevo nombre a una función? Por ejemplo, quiero usar el nombre holler
para printf
. #definir es obvio ... ¿de otra manera?
Soluciones:
#define holler printf
void (*p)() = fn; //function pointer
void (&r)() = fn; //function reference
inline void g(){ f(); }
void (&NewName)(some_vector&, float, float, float, float) = OldName;
en mi próxima visita.printf
esto. Eso fue solo un ejemplo. El problema aquí tiene más que ver con las limitaciones del inglés que con cualquier otra cosa. Tengo una sola función que sirve al propósito A y al propósito B, pero simplemente no puedo encontrar un nombre único que sirva para ambos propósitos aquí.T &a = b;
crea un nuevo nombre parab
.typedef
para tipos ynamespace A=B;
espacios de nombres.using BaseClass::BaseClassMethod
, y hayusing AliasType = Type;
, e incluso haynamespace AliasNamespace = Namespace;
. Lo que nos falta esusing AliasFunction = Function;
Respuestas:
Hay diferentes enfoques:
Con C ++ 11 con funciones no sobrecargadas sin plantilla, simplemente puede usar:
Si esta función tiene múltiples sobrecargas, debe usar
static_cast
:Ejemplo: hay dos sobrecargas de funciones
std::stoi
Si desea crear un alias para la primera versión, debe usar lo siguiente:
Nota: no hay forma de crear un alias para la función sobrecargada de modo que todas sus versiones sobrecargadas funcionen, por lo que siempre debe especificar qué sobrecarga de función exacta desea.
Con C ++ 14 puede ir aún más lejos con
constexpr
las variables de plantilla. Eso le permite alias funciones con plantilla:Además, comenzando con C ++ 11 tiene una función llamada
std::mem_fn
que permite alias funciones miembro. Vea el siguiente ejemplo:fuente
constexpr
enfoque de variables de plantilla: el alias no puede realizar una deducción de tipo. El compilador requiere que proporcione una lista de parámetros de plantilla (estoy escribiendo una función de plantilla variable): no se puede hacer referencia a la plantilla de variable `alias_to_old 'sin una lista de argumentos de plantillaconstexpr auto new_fn_name = old_fn_name
funciona en C ++ 11 (al menos en gcc 4.9.2) y es mejor que colocar&
. No requiere que la llamada se realice siempre a través de un puntero y, por lo tanto, permite que la función esté en línea en lugar de la llamada.constexpr auto holler = [] ( auto &&...args ) { return printf( std::forward<decltype(args)>( args )... ); };
std::mem_fn
es un alias ya que realiza mucha más magia detrás del sentido.Puede crear un puntero de función o una referencia de función:
fuente
fn
, usando el alias? ¿Puede explicar el puntero de función y la referencia de función? ¿En qué se diferencian? ¿Son iguales aquí?r();
void (&r)() = this->fn;
Debería estar bien.
fuente
decltype
como se introdujo en c ++ 11. Además, este también debe trabajar con el bueno de C. llanuraint (*holler)(const char*, ...) = std::printf;
fuente
Utilice una envoltura en línea. Obtiene ambas API, pero conserva la implementación única.
fuente
De fluentcpp : ALIAS_TEMPLATE_FUNCTION (f, g)
fuente
Vale la pena mencionar aquí, en mi opinión, que si bien la pregunta original (y las excelentes respuestas) son definitivamente útiles si desea cambiar el nombre de una función (¡hay buenas razones para hacerlo!), Si todo lo que desea hacer es eliminar un espacio de nombres profundo, pero mantener el nombre, existe la
using
palabra clave para esto:Esto también tiene la ventaja de que se limita a un ámbito, aunque siempre se puede utilizar en el nivel superior de un archivo. A menudo utilizo esto para
cout
yendl
así que no necesito llevar en todasstd
con el clásicousing namespace std;
en la parte superior de un archivo, pero también es útil si usted está usando algo comostd::this_thread::sleep_for()
una gran cantidad en un solo archivo o función, pero no en todas partes, y ninguna otra función del espacio de nombres. Como siempre, se desaconseja usarlo en archivos .h, o contaminará el espacio de nombres global.Esto no es lo mismo que el "cambio de nombre" anterior, pero a menudo es lo que realmente se desea.
fuente
Con lambdas genéricas C ++ 14, pude hacer lo siguiente, que también debería funcionar cuando la función de destino tiene múltiples sobrecargas:
fuente