比方说,我有两个指针,两个结构a
和b
。这两个结构均包含一个枚举,我们将其称为x
。给定所有可能的a
和b
,我想根据其x
枚举的值调用特定的函数。在我的案例中,有趣的是我要调用的函数如下所示:
X0_to_X1();
X0_to_X2();
...
X1_to_X0();
...
etc
其中X0
,X1
等是枚举的可能值x
,这意味着有X_to_Y
对于每个功能和的值的每个组合x
的枚举。
一个明显的“天真”解决方案将是一个switch语句,该语句会很大(考虑到x
有很多可能的值):
switch (a->x) {
case X0:
switch (b->x) {
case X1:
X0_to_X1();
break;
// ... and so on and so forth for every possible pair!
为了更好地解决这个问题,我的第一个尝试是实现一个宏,该宏在给定两个值的情况下x
可以形成函数调用:
#define CALL_FUNCTION(x1, x2) x1 ## _to_ ## x2 ()
但是,这是行不通的,因为在我的代码中,我永远无法知道运行时之前的实际值x
,因此最终看起来像:
CALL_FUNCTION(a->x, b->x);
当然可以转换为:
a->x_to_b->x();
这绝对没有道理。
有没有一种方法可以更优雅地解决此问题,或者我应该只是硬着头皮,而是执行大量的switch语句?
查找表会激怒这个问题,在该表中您存储了指向各种函数的指针,并且这些指针由枚举值进行键控。
如果您的enum
值是顺序的(并且没有两个枚举常量共享相同的值),则可以将查找表构建为简单的2D数组:
enum x_t { X0, X1, X2, ..., NUM_X };
void (*lookup[NUM_X][NUM_X])(void) = {
{ NULL, X0_to_X1, X0_to_X2, X0_to_X3, ... },
{ X1_to_X0, NULL, X1_to_X2, X1_to_X3, ... },
{ X2_to_X0, X2_to_X1, NULL, X2_to_X3, ... },
...
};
假定您x
和y
相同时没有“身份”功能。
然后,通过索引到表中来调用所需的函数,如下所示:
if ( x != y )
lookup[x][y]();
不,它不是很漂亮,但是它击败了嵌套switch
语句。您可以根据需要将其隐藏在宏或其他函数调用之后。
如果枚举值不是连续的,则此特定实现将无法正常工作-您必须使用列表或稀疏矩阵以其他方式构建查找表。但是,尽管设置代码可能很乏味,但它将大大简化调用方的逻辑。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句