编译字符串键控哈希的时间分辨率

时间:2017-01-09 16:37:26

标签: c++

我正在编写一个用于从预定义元素字符串表生成位掩码的类:

const std::unordered_map<std::string, int> flagMap
{ { "bananas", 0x1 }, { "apples", 0x2 }, { "oranges", 0x4 }, { "pears", 0x8 }};

int fruitMask(std::string & fruitName)
{
    if(flagMap.count(fruitName) > 0)
        return flagMap.at(fruitName);
    else
        return 0;
}

int fruitMask(const char * fruitName)
{
    if(flagMap.count(fruitName) > 0)
        return flagMap.at(fruitName);
    else
        return 0;
}    

int fruitMask(std::vector<std::string> fruitNames)
{
    int result = 0;

    for(auto it=fruitNames.begin(); it!=fruitNames.end(); ++it)
    {
        if(flagMap.count(*it) > 0)
            result = result | flagMap.at(*it);
    }

    return result;
} 

int fruitMask(std::initializer_list<const char*> fruitNames)
{
    int result = 0;

    for(auto it=fruitNames.begin(); it!=fruitNames.end(); ++it)
    {
        if(flagMap.count(*it) > 0)
            result = result | flagMap.at(*it);
    }

    return result;
}    

当使用这些函数的代码调用const char*的{​​{1}}或std::initializer_list<const char*>版本时,有没有办法让它在编译时工作?

例如:

fruitMask

这不会编译因为flagMask()不是constexpr,有没有办法使这个工作?这需要constexpr unordered_map,我甚至不知道这是否可行。

1 个答案:

答案 0 :(得分:0)

讨论了编译时间字符串here

也许不是答案本身,但(希望)是一个有用的暗示。 它不仅仅是关于你的情况下的无序映射,而是关于你的密钥,const char*在一般情况下并不真正意味着编译时字符串,你会考虑更改密钥类型吗?让我们考虑enum - ed键(非常不是最优的二次搜索,抱歉):

#include <utility>

enum class keys : char 
{
   foo,
   bar,
   baz,
   lol
};

static constexpr std::pair<keys, int> flagMap[] = {
  {keys::foo, 42},
  {keys::bar, 24},
  {keys::baz, 100500},
  {keys::lol, 15234}
};

static constexpr int sum(std::initializer_list<keys> target)
{
  int res{0};
  for (auto key: target) { 
    for (int i = 0; i < 4; ++i)
    {
      res += (flagMap[i].first == key) ? flagMap[i].second : 0;
    }
  }
  return res;
}

int main()
{
  return sum({keys::foo, keys::baz});
}

Demo仅产生

mov     eax, 100542
ret

在-O1及以上