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

C++ 如何在C+;中为函数名分配别名+;?,c++,alias,C++,Alias,为类型、变量或命名空间创建新名称很容易。但是如何为函数指定新名称呢?例如,我想对printf使用名称holler#定义是显而易见的。。。还有别的办法吗 解决方案: #定义holler printf void(*p)(=fn//函数指针 void(&r)(=fn//功能参考 inline void g(){f();} int(*holler)(常量字符*,…)=std::printf typedef int (*printf_alias)(const char*, ...); printf_ali

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

解决方案:

  • #定义holler printf
  • void(*p)(=fn//函数指针
  • void(&r)(=fn//功能参考
  • inline void g(){f();}
  • int(*holler)(常量字符*,…)=std::printf

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

    应该可以。您可以创建函数指针或函数引用:

    void fn()
    {
    }
    
    //...
    
    void (*p)() = fn;//function pointer
    void (&r)() = fn;//function reference
    

    使用内联包装器。您可以同时获得两个API,但保留单个实现。

    有不同的方法:

    • 使用带有非模板非重载函数的C++11,您只需使用:

      const auto& new_fn_name = old_fn_name;
      
    • 如果此函数有多个重载,则应使用
      静态\u cast

      const auto& new_fn_name = static_cast<OVERLOADED_FN_TYPE>(old_fn_name);
      
      如果要为第一个版本创建别名,应使用以下命令:

      const auto& new_fn_name = static_cast<int(*)(const string&, size_t*, int)>(std::stoi);
      
    • 此外,从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);
      
      结构A{ 无效f(内部i){ std::coutFrom:ALIAS\u TEMPLATE\u函数(f,g)

      #定义别名(模板)函数(高级别、低级别)\
      模板\
      内联自动高电平(Args&&…Args)->decltype(低电平(std::forward(Args)…)\
      { \
      返回低电平(标准::转发(args)…)\
      }
      
      在这里值得一提的是,如果您想重命名函数(有很好的理由这么做!),那么原始问题(以及很好的答案)肯定很有用,如果您只想去掉一个很深的名称空间,但保留名称,那么有一个
      使用
      关键字:

      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
      与经典的
      使用名称空间std;
      一起放在文件的顶部,但是如果您正在使用某个ng类似于
      std::this_thread::sleep_for()
      在一个文件或函数中有很多,但不是在所有地方,也不是命名空间中的任何其他函数。一如既往,不鼓励在.h文件中使用它,否则会污染全局命名空间


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

      使用C++14 generic lambdas,我可以执行以下操作,当目标函数具有多个重载时,这也应该可以工作:

      constexpr auto holler = [] ( auto &&...args ) {
              return printf( std::forward<decltype(args)>( args )... );
          };
      
      constexpr auto-holler=[](auto&&…args){
      返回printf(std::forward(args)…);
      };
      
      这很重要。我不知道函数引用。@Vulcan:它们几乎是一样的,你可以用相同的语法调用它们,但它们的地址有点不同。r不占用自己的内存空间来保存地址。你如何使用别名调用
      fn
      ?你能解释一下函数指针和函数吗离子引用?它们有什么不同?它们在这里是一样的吗?@Matt,你对它的称呼和你对fn的称呼完全一样。
      r();
      对于一个实例方法,你会怎么称呼它呢?编辑:这似乎是编译:
      void(&r)(=this->fn;
      谢谢大家。我的同事们会喜欢看到
      void(&NewName)(一些向量&浮点,浮点,浮点,浮点,浮点)=OldName;
      在我下一次签入时。他们不会喜欢看到你在标准库函数中使用随机名称。我不会在这里处理
      printf
      。这只是一个例子。这里的问题更多地与英语的局限性有关。我有一个函数用于用途a和用途B,但我有一个我在这里根本找不到一个能同时起两个作用的名字。@Neil,准确地说。
      T&a=b;
      b
      typedef
      为类型和
      命名空间a=b;
      创建了一个新名字。有
      使用BaseClass::BaseClassMethod
      ,还有
      使用AliasType=Type;
      ,甚至还有
      namespace-AliasNamespace=namespace;
      。我们缺少的是
      使用AliasFunction=Function;
      在全局名称空间中不是printf吗?如果包含它,它是全局的,但如果包含@einpoklum,它在std中是全局的:这没有什么问题,但答案是从2010年开始的。那时没有引入
      decltype
      在c++11中。此外,这也适用于好的旧的普通c。很好,c++98如何?我有一个类,用于设置和重置。在内部,没有问题。对于外部用户,我想别名为“set”,以便上下文直观(设置一个默认的构造,clear()'d等;重置工作对象)。类方法:(1)“void”(&set)(const string&,const bool,const bool);“(2)void(&set)(const string&,const int,const bool);2“reset”与相应的签名一起工作。既然我在类声明中有签名,我可以只初始化类::set(reset),set(reset)。如果没有,显式静态_cast示例是否有效?模板变量方法似乎存在问题:
      constepr
      别名无法进行类型推断。编译器要求我提供模板参数列表(我正在编写可变模板函数):在没有模板参数列表的情况下,无法引用变量模板“alias_to_old”(别名)
      constexpr auto new_fn_name=old_fn_name
      在C++11中工作(至少在gcc 4.9.2中)并且比放置
      &
      更好。它不需要始终通过指针执行调用,因此允许函数内联以代替调用。使用C++14通用lambda,我能够执行以下操作,这在目标函数具有多个重载时也应能工作:
      constepr auto-holler=[](auto&&…args){
      
      #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)...); \
      }
      
      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
      }
      
      constexpr auto holler = [] ( auto &&...args ) {
              return printf( std::forward<decltype(args)>( args )... );
          };