Utworzenie nowej nazwy dla typu, zmiennej lub przestrzeni nazw jest łatwe. Ale jak przypisać nową nazwę do funkcji? Na przykład chcę użyć nazwy holler
dla printf
. #define jest oczywiste ... w inny sposób?
Rozwiązania:
#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;
moim następnym zameldowaniem.printf
. To był tylko przykład. Problem tutaj bardziej dotyczy ograniczeń języka angielskiego niż czegokolwiek innego. Mam jedną funkcję służącą do celu A i celu B, ale po prostu nie mogę znaleźć tutaj jednej nazwy służącej do obu celów.T &a = b;
tworzy nową nazwę dlab
.typedef
dla typów inamespace A=B;
dla przestrzeni nazw.using BaseClass::BaseClassMethod
i jestusing AliasType = Type;
i jest nawetnamespace AliasNamespace = Namespace;
. To, czego nam brakuje, tousing AliasFunction = Function;
Odpowiedzi:
Istnieją różne podejścia:
W C ++ 11 z funkcjami nie będącymi szablonami, które nie są przeciążone, możesz po prostu użyć:
Jeśli ta funkcja ma wiele przeciążeń, powinieneś użyć
static_cast
:Przykład: istnieją dwa przeciążenia funkcji
std::stoi
Jeśli chcesz utworzyć alias do pierwszej wersji, powinieneś użyć:
Uwaga: nie ma sposobu na utworzenie aliasu do przeciążonej funkcji, tak aby wszystkie jej przeciążone wersje działały, dlatego zawsze należy określić, które dokładnie przeciążenie funkcji ma być wymagane.
Dzięki C ++ 14 możesz pójść jeszcze dalej ze
constexpr
zmiennymi szablonowymi. To pozwala na tworzenie aliasów funkcji opartych na szablonach:Co więcej, zaczynając od C ++ 11 masz funkcję o nazwie,
std::mem_fn
która umożliwia aliasowanie funkcji składowych. Zobacz poniższy przykład:źródło
constexpr
podejściem do zmiennych szablonu: alias nie może wykonywać dedukcji typu. Kompilator wymaga ode mnie podania listy parametrów szablonu (piszę zmienną funkcję szablonu): nie może odwoływać się do szablonu zmiennej `alias_to_old bez listy argumentów szablonuconstexpr auto new_fn_name = old_fn_name
działa w C ++ 11 (przynajmniej w gcc 4.9.2) i jest lepsze niż umieszczanie&
. Nie wymaga wywołania zawsze wykonywanego przez wskaźnik, dzięki czemu funkcja może być wstawiana w miejscu wywołania.constexpr auto holler = [] ( auto &&...args ) { return printf( std::forward<decltype(args)>( args )... ); };
std::mem_fn
to nie aliasem ponieważ wykonuje znacznie więcej magii za sensie.Możesz utworzyć wskaźnik funkcji lub odwołanie do funkcji:
źródło
fn
, używając aliasu? Czy możesz wyjaśnić wskaźnik funkcji i odniesienie do funkcji? Czym się różnią? Czy są tutaj takie same?r();
void (&r)() = this->fn;
Powinieneś dobrze.
źródło
decltype
jak zostało wprowadzone w c ++ 11. Co więcej, powinno to również działać z dobrym, starym zwykłym C.int (*holler)(const char*, ...) = std::printf;
źródło
Użyj wbudowanego opakowania. Otrzymujesz oba interfejsy API, ale zachowaj jedną implementację.
źródło
Od fluentcpp : ALIAS_TEMPLATE_FUNCTION (f, g)
źródło
Dzięki generycznym lambdom C ++ 14 mogłem wykonać następujące czynności, które powinny również działać, gdy funkcja docelowa ma wiele przeciążeń:
źródło
Warto tutaj wspomnieć IMO, że chociaż oryginalne pytanie (i świetne odpowiedzi) są zdecydowanie przydatne, jeśli chcesz zmienić nazwę funkcji (istnieją dobre powody, aby to zrobić!), Jeśli chcesz tylko usunąć głęboką przestrzeń nazw, ale zachowaj nazwę, jest
using
do tego słowo kluczowe:Ma to również tę zaletę, że ogranicza się do zakresu, chociaż zawsze można go użyć na najwyższym poziomie pliku. Często używam tego dla
cout
iendl
tak nie muszę sprowadzić wszystkichstd
z klasycznymusing namespace std;
na początku pliku, ale także przydatne, jeśli używasz coś jakstd::this_thread::sleep_for()
wiele w jednym pliku lub funkcji, ale nie wszędzie, nie żadne inne funkcje z przestrzeni nazw. Jak zawsze, odradza się używanie go w plikach .h, w przeciwnym razie zanieczyszczasz globalną przestrzeń nazw.To nie to samo, co „zmiana nazwy” powyżej, ale często jest to coś, czego naprawdę chcemy.
źródło