C++宏,用于调用基于枚举类型的函数
C++ - macro for calling function based on enum type
我有一个enum
和一个函数,它接受这个枚举并使用switch case
来调用正确的函数:
enum { FOO, BAR, ... } // 10-15 operations
void do_action() {
switch(enum) {
case FOO: fn_FOO(); break;
case BAR: fn_BAR(); break;
case default: fn_DEFAULT(); break;
}
}
我一直在试图找到一种使用Macros自动生成上述case语句的方法(以避免麻烦),但我是C++的新手,谷歌并没有提供太多帮助。
我知道有一种替代方法可以通过使用函数指针数组来避免一些样板案例语句,但我真的很想知道如何使用宏来实现这一点。
使用宏和标记粘贴应该相当简单,例如
#define do_action(e) fn_##e()
do_action(FOO); // -> fn_FOO();
do_action(BAR); // -> fn_BAR();
然而,这实际上是对2014年C++问题的20世纪80年代的C解决方案,您几乎肯定应该重新考虑。
要只重复枚举值一次,可以执行
#define FOOBAR do_FOOBAR(FOO) do_FOOBAR(BAR) // 10-15 operations
然后声明您的枚举:
#define do_FOOBAR(x) x,
enum E { FOOBAR };
#undef do_FOOBAR
对于交换机:
switch(e) {
#define do_FOOBAR(x) case x: fn_##x(); break;
FOOBAR
#undef do_FOOBAR
default:
fn_DEFAULT();
break;
}
##
运算符可用于将预处理器标记连接在一起以生成单个标记,因此您可以使用它将枚举器名称绑定到函数名称的公共前缀上:
#define CASE(X) case X: fn_##X(); break;
switch(e){ // "enum" not a valid identifier
CASE(FOO)
CASE(BAR)
default: fn_DEFAULT(); break; // needs to be treated differently
}
虽然这种怪物偶尔会有用,但在使用预处理器之前,请始终尝试在语言中执行您想要的操作。正如您所说,函数指针、虚拟函数或其他语言机制可能会在这里使用。
除了在某些情况下,比如条件编译等情况下,最好去其他方向,而不是宏所指向的方向。
我会使用一个映射,它将enum作为键,将函数指针作为其value_type。
相关文章:
- 强枚举类型定义:Clang Bug 还是 C++11 标准不确定性?
- 如何注册枚举类型到QJSEngine,以便在脚本环境中使用?
- 通过包装器从 C 访问C++ API 时,如何访问枚举类型
- C++/错误:表达式必须具有整数或无作用域枚举类型
- 如何理解c++中在命名空间内部定义的枚举类型enum
- 在类访问混淆中声明的枚举类型
- 在枚举类型上使用std::max是不是一种糟糕的做法
- C++ 在方程中使用变量;错误:表达式必须具有整数或无作用域枚举类型及其他
- 是否可以使用泛型枚举类型作为函数的参数?
- Visual Studio 2017 生成工具与枚举类型的问题
- 使用枚举类型管理存储顺序
- 如何检查类中定义的枚举类型变量是否被分配给?
- 如何从枚举类型中获取枚举值?
- 为什么C++不为枚举类型提供默认"operator>>"函数?
- 确保枚举类型的键/值在软件Revs之间永远不会更改
- MSVC 1 位枚举类型等于 -1,并且相等性测试失败
- 我们可以专业化类模板的枚举(类型)成员吗?
- 错误:以增量方式填充向量时,表达式必须具有整数或无作用域枚举类型
- 枚举类型的重载>>运算符(工作日)
- C 中的枚举类型字符串类别