É fácil criar um novo nome para um tipo, variável ou namespace. Mas como atribuo um novo nome a uma função? Por exemplo, quero usar o nome holler
para printf
. #define é óbvio ... alguma outra forma?
Soluções:
#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;
no meu próximo check-in.printf
aqui. Isso foi apenas um exemplo. O problema aqui tem mais a ver com as limitações do inglês do que com qualquer outra coisa. Tenho uma única função que atende ao propósito A e ao propósito B, mas simplesmente não consigo encontrar um único nome que atenda a ambos os propósitos aqui.T &a = b;
cria um novo nome parab
.typedef
para tipos enamespace A=B;
para namespaces.using BaseClass::BaseClassMethod
, existeusing AliasType = Type;
e existe aténamespace AliasNamespace = Namespace;
. O que está faltando éusing AliasFunction = Function;
Respostas:
Existem diferentes abordagens:
Com C ++ 11 com funções não sobrecarregadas de template, você pode simplesmente usar:
Se esta função tiver várias sobrecargas, você deve usar
static_cast
:Exemplo: existem duas sobrecargas de função
std::stoi
Se você quiser fazer um alias para a primeira versão, você deve usar o seguinte:
Observação: não há como criar um alias para a função sobrecarregada de forma que todas as suas versões sobrecarregadas funcionem, portanto, você deve sempre especificar qual sobrecarga de função exata deseja.
Com C ++ 14, você pode ir ainda mais longe com
constexpr
variáveis de modelo. Isso permite que você crie um alias de funções com modelo:Além disso, começando com C ++ 11, você tem uma função chamada
std::mem_fn
que permite alias a funções-membro. Veja o seguinte exemplo:fonte
constexpr
abordagem das variáveis de modelo: o alias não pode fazer dedução de tipo. O compilador requer que eu forneça uma lista de parâmetros de modelo (estou escrevendo uma função de modelo variadic): não posso referir-se ao modelo de variável `alias_to_old 'sem uma lista de argumentos de modeloconstexpr auto new_fn_name = old_fn_name
funciona em C ++ 11 (pelo menos no gcc 4.9.2) e é melhor do que colocar&
. Não requer que a chamada seja sempre feita por meio de um ponteiro e, portanto, permite que a função seja embutida no lugar da chamada.constexpr auto holler = [] ( auto &&...args ) { return printf( std::forward<decltype(args)>( args )... ); };
std::mem_fn
é um apelido, pois faz muito mais mágica por trás do sentido.Você pode criar um ponteiro de função ou uma referência de função:
fonte
fn
, usando o alias? Você pode explicar o ponteiro de função e a referência de função? Como eles são diferentes? Eles são iguais aqui?r();
void (&r)() = this->fn;
Você deve estar bem.
fonte
decltype
como foi introduzido em c ++ 11. Além disso, isso também deve funcionar com o bom e velho C.int (*holler)(const char*, ...) = std::printf;
fonte
Use um invólucro embutido. Você obtém ambas as APIs, mas mantém a implementação única.
fonte
De fluentcpp : ALIAS_TEMPLATE_FUNCTION (f, g)
fonte
Com lambdas genéricos do C ++ 14, consegui fazer o seguinte, o que também deve funcionar quando a função de destino tem várias sobrecargas:
fonte
Vale a pena mencionar aqui, IMO, que embora a pergunta original (e ótimas respostas) seja definitivamente útil se você quiser renomear uma função (há boas razões para fazer isso!), Se tudo o que você deseja fazer é retirar um namespace profundo, mas mantenha o nome, há uma
using
palavra - chave para isso:Isso também tem a vantagem de ser confinado a um escopo, embora você sempre possa usá-lo no nível superior de um arquivo. Costumo usar isso
cout
e,endl
portanto, não preciso trazer TODOSstd
com o clássicousing namespace std;
no início de um arquivo, mas também é útil se você estiver usando algostd::this_thread::sleep_for()
em um arquivo ou função, mas não em todos os lugares, e nenhuma outra função do namespace. Como sempre, não é recomendável usá-lo em arquivos .h, ou você poluirá o namespace global.Isso não é o mesmo que "renomear" acima, mas geralmente é o que realmente se deseja.
fonte