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