Подтвердить что ты не робот

Каков наилучший способ переименования (псевдонима/вперед) функции в С++?

(Я ограничу этот вопрос на С++ 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)
}}
4b9b3361

Ответ 1

Это действительно общий?

Да.

Это самый простой способ?

Да (к сожалению).

Это оптимальный способ? (например, могут быть встроены, без лишних копий)

Да.

Что, если исходная функция имела некоторые функции SFINAE? (например, template<class A, class B, class C, class = std::enable_if< ... >::type>), будет ли во всех случаях передавать SFINAE?

Да, если выражение внутри decltype дает ошибку (т.е. fun не существует, возможно, из-за SFINAE на fun), это вызовет SFINAE для gun, а также удалит его из набор перегрузки.

Что, если исходная функция вернула ссылки? Разве declctpe не удаляет тип ссылок?. (например, double& fun(double& x){return x;}).

Нет, зачем?

То же самое можно сказать о функциях-членах, хотя это нужно сделать, модифицируя класс, который я предполагаю.

Это не вопрос. Что можно сказать о функциях члена? Все вышеизложенное применимо в равной степени.