我有一个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;
}
}
我一直试图找到一种方法来使用宏来自动生成上述案例陈述(以避免锅炉板),但我是C ++的新手并且google还没有多大帮助。
我已经意识到通过使用函数指针数组来避免某些样板案例语句的另一种方法,但我真的很想知道如何使用宏来完成这项工作。
答案 0 :(得分:3)
宏和令牌粘贴应该相当简单,例如
#define do_action(e) fn_##e()
do_action(FOO); // -> fn_FOO();
do_action(BAR); // -> fn_BAR();
然而,这确实是20世纪80年代的C解决方案,解决了2014 C ++问题,你几乎肯定会重新考虑。
答案 1 :(得分:1)
##
运算符可用于将预处理程序标记连接在一起以生成单个标记,因此您可以使用它将枚举器名称提取到函数名称的公共前缀:
#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
}
虽然这些怪物偶尔会有用,但在到达预处理器之前,总是尽量在语言中做你想做的事情。正如你所说,这里可能会使用函数指针,虚函数或其他一些语言机制。
答案 2 :(得分:1)
要仅重复一次枚举值,您可以
#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;
}
答案 3 :(得分:0)
除了在条件编译等情况下,除了宏指向以外,其他方向总是更好。
我会使用一个将枚举作为键和函数指针作为其value_type的映射。