为类型,变量或命名空间创建新名称很容易.但是如何为函数指定新名称?例如,我想使用的名称holler进行printf.#define很明显......还有其他方式吗?
解决方案:
#define holler printfvoid (*p)() = fn; //function pointervoid (&r)() = fn; //function referenceinline void g(){ f(); }sas*_*hka 106
有不同的方法:
使用带有非模板非重载函数的C++ 11,您可以简单地使用:
const auto& new_fn_name = old_fn_name;
Run Code Online (Sandbox Code Playgroud)如果此函数有多个重载,您应该使用static_cast:
const auto& new_fn_name = static_cast<OVERLOADED_FN_TYPE>(old_fn_name);
Run Code Online (Sandbox Code Playgroud)
示例:函数有两个重载 std::stoi
int stoi (const string&, size_t*, int);
int stoi (const wstring&, size_t*, int);
Run Code Online (Sandbox Code Playgroud)
如果要为第一个版本创建别名,则应使用以下内容:
const auto& new_fn_name = static_cast<int(*)(const string&, size_t*, int)>(std::stoi);
Run Code Online (Sandbox Code Playgroud)
注意:无法为重载函数创建别名,使其所有重载版本都能正常工作,因此您应始终指定所需的确切函数重载.
使用C++ 14,您可以进一步使用constexpr模板变量.这允许您为模板化函数添加别名:
template<typename T>
constexpr void old_function(/* args */);
template<typename T>
constexpr auto alias_to_old = old_function<T>;
Run Code Online (Sandbox Code Playgroud)此外,从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);
Run Code Online (Sandbox Code Playgroud)Bri*_*ndy 34
您可以创建函数指针或函数引用:
void fn()
{
}
//...
void (*p)() = fn;//function pointer
void (&r)() = fn;//function reference
Run Code Online (Sandbox Code Playgroud)
jer*_*jer 21
typedef int (*printf_alias)(const char*, ...);
printf_alias holler = std::printf;
Run Code Online (Sandbox Code Playgroud)
你应该没事吗?
使用 C++14 泛型 lambda,我能够执行以下操作,当目标函数具有多个重载时,这也应该起作用:
constexpr auto holler = [] ( auto &&...args ) {
return printf( std::forward<decltype(args)>( args )... );
};
Run Code Online (Sandbox Code Playgroud)
来自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)...); \
}
Run Code Online (Sandbox Code Playgroud)
在这里值得一提的是,虽然最初的问题(和很好的答案)如果你想重命名一个函数(有充分的理由这样做!)绝对有用,但如果你想做的只是去掉一个深层的命名空间,但是保留名称,有一个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
}
Run Code Online (Sandbox Code Playgroud)
这还有一个优点,即它被限制在一个范围内,尽管您始终可以在文件的顶层使用它。我经常使用它cout,endl所以我不需要在文件顶部引入所有std经典内容,但如果您在一个文件或函数中使用很多东西,但不是在任何地方,那么这也很有用,并且不是命名空间中的任何其他函数。与往常一样,不鼓励在 .h 文件中使用它,否则会污染全局命名空间。using namespace std;std::this_thread::sleep_for()
这与上面的“重命名”不同,但通常是真正想要的。