шаблоны — Каков наилучший способ переименования (псевдоним / пересылка) функции в 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 передать СФИНА во всех случаях?
  • Что если исходная функция вернула ссылки? Разве decltype не собирается удалять тип ссылок? (например. double& fun(double& x){return x;}).
  • То же самое можно сказать и о функциях-членах?

Разъяснение: gun никогда не будет именно так 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)
}}

20

Решение

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

Да.

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

Да (печально)

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

Да.

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

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

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

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

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

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

10

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]