Как назначить псевдоним имени функции в C ++? - PullRequest
91 голосов
/ 16 июня 2010

Легко создать новое имя для типа, переменной или пространства имен.Но как мне назначить новое имя функции?Например, я хочу использовать имя holler для printf.# определение очевидно ... любым другим способом?

Решения:

  1. #define holler printf
  2. void (*p)() = fn; //function pointer
  3. void (&r)() = fn; //function reference
  4. inline void g(){ f(); }

Ответы [ 7 ]

101 голосов
/ 20 сентября 2013

Существуют разные подходы:

  • С C ++ 11 с не перегруженными функциями без шаблонов вы можете просто использовать:

    const auto& new_fn_name = old_fn_name;
    
  • Если эта функция имеет несколько перегрузок, вы должны использовать static_cast:

    const auto& new_fn_name = static_cast<OVERLOADED_FN_TYPE>(old_fn_name);
    

    Пример: есть две перегрузки функции std::stoi

    int stoi (const string&, size_t*, int);
    int stoi (const wstring&, size_t*, int);
    

    Если вы хотите сделатьВ качестве псевдонима для первой версии вы должны использовать следующее:

    const auto& new_fn_name = static_cast<int(*)(const string&, size_t*, int)>(std::stoi);
    

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

  • С C ++ 14 вы можете пойти еще дальше с constexpr переменными шаблона.Это позволяет вам создавать псевдоним шаблонных функций:

    template<typename T>
    constexpr void old_function(/* args */);
    
    template<typename T>
    constexpr auto alias_to_old = old_function<T>;
    
  • Более того, начиная с C ++ 11, у вас есть функция с именем std::mem_fn, которая позволяет псевдонимы функций-членов.Смотрите следующий пример:

    struct A {
       void f(int i) {
          std::cout << "Argument: " << i << '\n';
       }
    };
    
    
    A a;
    
    auto greet = std::mem_fn(&A::f); // alias to member function
    // prints "Argument: 5"
    greet(a, 5); // you should provide an object each time you use this alias
    
    // if you want to bind an object permanently use `std::bind`
    greet_a = std::bind(greet, a, std::placeholders::_1);
    greet_a(3); // equivalent to greet(a, 3) => a.f(3);
    
33 голосов
/ 16 июня 2010

Вы можете создать указатель функции или ссылку на функцию:

void fn()
{
}

//...

void (*p)() = fn;//function pointer
void (&r)() = fn;//function reference
21 голосов
/ 16 июня 2010
typedef int (*printf_alias)(const char*, ...);
printf_alias holler = std::printf;

Должен ли ты в порядке.

10 голосов
/ 16 июня 2010

int (*holler)(const char*, ...) = std::printf;

7 голосов
/ 16 июня 2010

Используйте встроенную оболочку. Вы получаете оба API, но сохраняете единственную реализацию.

2 голосов
/ 04 января 2018

С fluentcpp : ALIAS_TEMPLATE_FUNCTION (f, g)

#define ALIAS_TEMPLATE_FUNCTION(highLevelF, lowLevelF) \
template<typename... Args> \
inline auto highLevelF(Args&&... args) -> decltype(lowLevelF(std::forward<Args>(args)...)) \
{ \
    return lowLevelF(std::forward<Args>(args)...); \
}
0 голосов
/ 04 января 2019

Стоит упомянуть здесь IMO, что хотя оригинальный вопрос (и отличные ответы) определенно полезны, если вы хотите переименовать функцию (есть веские причины для этого!), Если все, что вы хотите сделать, это удалить глубокое пространство имен, но оставьте имя, для этого есть ключевое слово using:

namespace deep {
  namespace naming {
    namespace convention {
      void myFunction(int a, char b) {}
    }
  }
}
int main(void){
  // A pain to write it all out every time
  deep::naming::convention::myFunction(5, 'c');

  // Using keyword can be done this way
  using deep::naming::convention::myFunction;
  myFunction(5, 'c');  // Same as above
}

Это также имеет то преимущество, что оно ограничено областью действия, хотя вы всегда можете использовать его на верхнем уровне файла. Я часто использую это для cout и endl, поэтому мне не нужно вводить ВСЕ std с классическим using namespace std; в начале файла, но также полезно, если вы используете что-то вроде std::this_thread::sleep_for() много в одном файле или функции, но не везде, и не любые другие функции из пространства имен. Как всегда, не рекомендуется использовать его в файлах .h, иначе вы загрязните глобальное пространство имен.

Это не то же самое, что "переименование" выше, но часто это то, что действительно нужно.

...