1

我正在用 C++ 实现一个协议模型(特别是缓存一致性协议,但这对于这个问题并不重要)

该协议有两个值: aprevious_state和 a message_type。两者都是枚举。协议应该为两个输入的每个组合选择一个唯一的操作。一些组合无效(应该显示错误),一些组合将被停止。

用 C++ 对上述场景进行编码的好方法是什么?我能想到:两个嵌套的 switch 块来选择一个输入组合,并调用一个特定的动作实现为一个函数。

是否有一些更优雅和灵活的方式来编码上述场景?理想情况下,从协议中添加/删除输入组合应该很容易。

感谢您的任何建议。(我是设计模式的新手,不知道有什么适合这里的)

4

2 回答 2

1

假设这两个枚举是 32 位值。我会做这样的事情:

void doit(E1 previous_state, E2 message_type) {
# define COMBINE(_x_, _y_) (static_cast<int64_t>(previous_state) << 32 | message_type)
  switch (COMBINE(previous_state, message_type) {
  case COMBINE(e1value1, e2value1):
    // ...
    break;
  case COMBINE(e1value4, e2value3):
    // ...
    break;
  // ... more cases ...
  default:
    // report error
  }
}

不要假设这会生成更快的代码——switch 语句通常被优化到跳转表中,但是像这样的技巧可能会打败它。如果您最感兴趣的是尽可能最佳的性能,则必须进行试验并找出最适合您的系统的方法(注意将 int64_t 更改为较小的类型并最小化我的示例中的变化可能会产生一些影响)。

于 2013-04-14T07:25:46.733 回答
1

为什么不使用简单的二维数组?例如

enum Previous_state
{
state_1 = 0,
state_2,
...,
state_n,
PreviousLastValue
}

enum Message_type
{
type_1 = 0,
type_2,
...,
type_n,
TypeLastValue
}
...

Action actions[PreviousLastValue][TypeLastValue] = {NULL}; 

void SetAction(Previous_state state, Message_type type, Action action)
{
    actions[state][type] = action;
}

void RemoveAction(Previous_state state, Message_type type)
{
    actions[state][type] = 0;
}

void GetAction(Previous_state state, Message_type type)
{
    if(actions[state][type] == 0)
    {
        //display error
    }

    return actions[state][type];
}
于 2013-04-14T07:41:22.283 回答