如何在 C + + 中为函数名指定别名?

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

解决方案:

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

int (*holler)(const char*, ...) = 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

Use an inline wrapper. You get both APIs, but keep the single implementation.

有不同的方法:

  • 使用 C + + 11和非模板非重载函数,你可以简单地使用:

    const auto& new_fn_name = old_fn_name;
    
  • If this function has multiple overloads you should use 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>;
    
  • Moreover, starting with C++11 you have a function called std::mem_fn that allows to alias member functions. See the following example:

    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);
    

From 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)...); \
}

在这里值得一提的是 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
}

这样做还有一个优点,即它被限制在一个范围内,尽管您总是可以在文件的顶层使用它。我经常在 coutendl中使用它,所以我不需要在一个文件的顶部引入所有的 std和经典的 using namespace std;,但是如果你经常在一个文件或函数中使用类似于 std::this_thread::sleep_for()的东西,但是不是在所有地方,也不是在名称空间中的任何其他函数中使用它,那么它也很有用。像往常一样,不鼓励使用它。H 文件,否则将污染全局命名空间。

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

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

constexpr auto holler = [] ( auto &&...args ) {
return printf( std::forward<decltype(args)>( args )... );
};