用文字地图替换简单的开关。什么地图?

时间:2017-08-17 11:47:35

标签: c++

我在很多地方都有以下模式:

unsigned key = getKey();
auto res = [=]() {
  switch (key)
  {
    case 12: return &x;
    case 14: return &y;
    case 81: return &z;
    default: fatal_error();
  }
}();

它是从非连续整数(通常是枚举)到其他一些值(通常是函数指针)的映射。开关结构适用于此但包含大量线路噪声。可以通过分配给变量来替换立即调用的lambda,以换取大量break;语句。

写这个的干净,规范的方法是什么?对于连续的整数,它可以是:

std::array<ptr_t, 3> map = {{&x, &y, &z}};  
auto res = map[key];

一种选择是使用地图(有序或无序),

std::map<unsigned, ptr_t> map = {{12, &x}, {14, &y}, {81, &z}};
auto res = map[key];

在代码清晰度方面哪个好,但相对不太可能被编译器剥离,因为映射涉及树和一堆堆分配。

另一个是通过哈希函数

std::array<ptr_t, 4> map = {{&y, &z, nullptr, &x}};
auto res = map[hash(key)]; // don't want to write hash() each time

我不介意,只要不涉及堆,调度是通过近乎完美的散列函数进入数组还是通过分支。可以改进上述开关吗?

来自nwp的建议:

using kvp_t = std::pair<unsigned, ptr_t>;
std::array<kvp_t, 3> m = {{
  {12, &x}, {14, &y}, {81, &z},
}};
auto res = std::find_if(m.begin(),m.end(),[=](kvp_t k) {
  return k.first == key;
})->second;

0 个答案:

没有答案