(Я ограничу этот вопрос на С++ 11, так как я полагаю, что нет общего способа сделать это на С++ 98).
Предположим, что у меня сложный (с точки зрения подписи) набор функций шаблона и/или перегруженные функции, и я хочу использовать эти функции точно так же, но используя другое имя (то есть псевдоним).
Например:
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
Теперь предположим, что я хочу переименовать (или псевдоним или переслать, чтобы быть более точным) эти функции, все сразу (т.е. иметь возможность использовать другое имя для одной и той же функции без перезаписи). Таким образом, в других частях кода я могу использовать его с другим именем и без изменения вышеуказанного кода.
Это правильный способ переименовать (псевдоним/вперед) fun
в gun
?
template<typename... Args>
inline auto gun(Args&&... args)->decltype(fun(std::forward<Args>(args)...)){
return fun(std::forward<Args>(args)...);
}
- Это действительно общий?
- Это самый простой способ?
- Это оптимальный способ? (например, могут быть встроены, без лишних копий).
- Что делать, если исходная функция имеет некоторые функции SFINAE? (например,
template<class A, class B, class C, class = std::enable_if< ... >::type>
), будет лиdecltype
передавать SFINAE во всех случаях? - Что делать, если исходная функция вернула ссылки? Разве declctpe не удаляет тип ссылок?. (например,
double& fun(double& x){return x;}
). - Можно ли так же сказать о функциях члена?
Уточнение: gun
никогда не будет точно fun
, так как экземпляры будут иметь разные адреса, но то, что я ищу, является переименованием для точки зрения общего кодирования.
Комментарий: мне кажется странным, что почти все можно переименовать/переадресовать, пространства имен, типы (typedef
) и типы шаблонов using typedef
, но не функции (или, в этом случае, функции-члены).
EDIT. Для полноты и, как представляется, это способ сделать это, здесь я добавил макрос для определения псевдонимов функций:
#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)...); \
}
а затем вы используете его следующим образом:
namespace NS1{namepsace NS2{
ALIAS_FUNCTION(NSA::fun, gun); // second argument (target name can't have namespace)
}}