Jaki jest najlepszy sposób zmiany nazwy (alias / forward) funkcji w C ++?
(Ograniczę to pytanie do C ++ 11, ponieważ uważam, że nie ma ogólnego sposobu na zrobienie tego w C ++ 98).
Przypuszczam, że mam skomplikowany (pod względem podpisu) zestawszablon funkcje i / lub przeciążone funkcje i chcę używać tych funkcji dokładnie w ten sam sposób, ale używając innej nazwy (to znaczy aliasu).
Na przykład:
template<class A, class B, class C>
D fun(A a, B& b, C&& c){ ... }
template<class E, class F>
G fun(H<E> he, F& f){ ... }
... many other versions of fun
Załóżmy teraz, że chcęPrzemianować (lubAliaslubNaprzód aby być bardziej precyzyjnym: te funkcje jednocześnie (tj. móc użyć innej nazwy dla tej samej funkcji bez przepisywania jej). Tak, że w innych częściach kodu mogę go używać pod inną nazwą i bez modyfikowania powyższego kodu.
Czy to właściwy sposóbPrzemianować (alias / do przodu)fun
wgun
?
template<typename... Args>
inline auto gun(Args&&... args)->decltype(fun(std::forward<Args>(args)...)){
return fun(std::forward<Args>(args)...);
}
Czy to jest naprawdę ogólne?Czy to najprostszy sposób?Czy to optymalny sposób? (np. można wstawić, nie ma niepotrzebnych kopii)Co jeśli oryginalna funkcja miała pewne funkcje SFINAE? (na przykład.template<class A, class B, class C, class = std::enable_if< ... >::type>
), będziedecltype
przenieść SFINAE we wszystkich przypadkach?Co jeśli oryginalna funkcja zwróciła referencje? Czy decltype nie usunie typu referencji ?. (na przykład.double& fun(double& x){return x;}
).Czy można to powiedzieć o funkcjach członków?Wyjaśnienie:gun
nigdy nie będziedokładnie fun
, ponieważ instancje będą miały różne adresy, ale szukam zmiany nazwy z punktu widzenia kodowania ogólnego.
Komentarz: Dziwne jest to, że prawie wszystko można przemianować / przekazać, przestrzenie nazw, typy (typedef
) i typy szablonówusing typedef
, ale nie funkcje (lub w tym celu funkcje członka).
EDYTOWAĆ: Dla kompletności i ponieważ wydaje się, że jest to sposób na zrobienie tego, tutaj dodałem makro, aby zdefiniować aliasy funkcji:
#define ALIAS_FUNCTION(OriginalnamE, AliasnamE) \
template <typename... Args> \
inline auto AliasnamE(Args&&... args) -> decltype(OriginalnamE(std::forward<Args>(args)...)) { \
return OriginalnamE(std::forward<Args>(args)...); \
}
a następnie używasz go w ten sposób:
namespace NS1{namepsace NS2{
ALIAS_FUNCTION(NSA::fun, gun); // second argument (target name can't have namespace)
}}