我正在编写一个用于从预定义元素字符串表生成位掩码的类:
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,我甚至不知道这是否可行。
答案 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及以上