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

(я ограничу этот вопрос C++11, так как я считаю, что нет общего способа сделать это в C++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 во всех случаях?
  • что делать, если исходная функция возвращает ссылки? Разве decltype не собирается удалить тип ссылок?. (например,double& fun(double& x){return x;}).
  • можно ли то же самое сказать о функциях-членах?

пояснение: gun is никогда не будет ровно fun, поскольку экземпляры будут иметь разные адреса, но то, что я ищу, - это переименование с точки зрения общего кодирования.

комментарий: Я нахожу странным, что почти все может быть переименовано / перенаправлено, пространства имен, типы (typedef) и типы шаблона using typedef, но не функции (или функции-члены).


редактировать: для полноты, и так как это, кажется, путь для этого я добавил макрос для определения псевдонимов функций:

#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)
}}

1 ответов


это действительно генерал?

да.

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

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

это оптимальный способ? (например, может быть встроен, нет ненужных копий)

да.

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

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

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

нет, с чего бы это?

то же самое можно сказать о функциях-членах, хотя это необходимо сделать, изменив класс I догадка.

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