代码之家  ›  专栏  ›  技术社区  ›  Agnel Kurian

如何在C++中分配函数名的别名?

  •  89
  • Agnel Kurian  · 技术社区  · 16 年前

    为类型、变量或命名空间创建新名称很容易。但如何为函数指定一个新名称呢?例如,我想使用 holler 对于 printf . #很明显。。。还有别的办法吗?

    解决:

    1. #define holler printf
    2. void (*p)() = fn; //function pointer
    3. void (&r)() = fn; //function reference
    4. inline void g(){ f(); }
    7 回复  |  直到 16 年前
        1
  •  122
  •   sasha.sochka    10 年前

    • 使用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>;
      
    • 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);
      
        2
  •  35
  •   Brian R. Bondy    16 年前

    可以创建函数指针或函数引用:

    void fn()
    {
    }
    
    //...
    
    void (*p)() = fn;//function pointer
    void (&r)() = fn;//function reference
    
        3
  •  22
  •   jer    16 年前
    typedef int (*printf_alias)(const char*, ...);
    printf_alias holler = std::printf;
    

    你应该没事的。

        4
  •  10
  •   MSalters    16 年前

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

        5
  •  7
  •   John    16 年前

    使用内联包装器。两个api都有,但只保留一个实现。

        6
  •  6
  •   sailfish009    8 年前

    fluentcpp

    #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)...); \
    }
    
        7
  •  3
  •   Anthony Hall    5 年前

    用C++ 14的通用lambdas,我能够做到以下几点,当目标函数有多个重载时,也应该这样工作:

    constexpr auto holler = [] ( auto &&...args ) {
            return printf( std::forward<decltype(args)>( args )... );
        };
    
        8
  •  0
  •   Kevin Anderson    7 年前

    在这里值得一提的是,如果你想重命名一个函数(有很好的理由这么做!),那么最初的问题(和很好的答案)肯定很有用,如果您只想去掉一个很深的名称空间,但保留名称,那么 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文件中使用它,否则会污染全局命名空间。

    这与上面的“重命名”不同,但通常是真正需要的。