我希望只打印出“分组”枚举,但无法获得预期的行为。因此,基本上打印出指定基Values
中的所有枚举,直到没有任何后续的连续枚举值。枚举的每个“分组”都可以通过与掩码0xFFFF0000
进行AND运算来确定
诀窍是我可以迭代_map
枚举,但这样就没有一种简单的方法来检查对应的键是否存在。find
方法需要一个键,所以这不会有帮助。
P.S.:_map
已经存在,用于“其他”目的,所以我不能更改它
enum class Values : uint32_t
{
one = 0x00000000,
oneOne = 0x00000001,
oneTwo = 0x00000002,
two = 0x00010000,
twoOne = 0x00010001,
twoTwo = 0x00010002,
three = 0x00020000,
threeOne = 0x00020001,
threeTwo = 0x00020002,
//...
MAX
};
std::unordered_map<std::string, Values> _map =
{
{"one", Values::one},
{"oneOne", Values::oneOne},
{"oneTwo", Values::oneTwo},
{"two", Values::two},
{"twoOne", Values::twoOne},
{"twoTwo", Values::twoTwo}
};
我得到了如下的结果,但是没有一种方法可以在枚举值不存在的地方“中断”。
void foo(Values base)
{
uint32_t mask = static_cast<uint32_t>(base) & 0xffff0000;
for (Values i = base; i < Values::MAX; i = static_cast<Values>(static_cast<uint32_t>(i) + 1))
{
uint32_t curMask = static_cast<uint32_t>(i) & 0xffff0000;
if (curMask != mask)
{
break; // stop if we've reached a different upper 16 bits value
}
std::cout << std::hex << static_cast<uint32_t>(i) << "\n";
}
}
// expected calls with expected output
foo(Values::one); // should print: one, oneOne, oneTwo
foo(Values::oneOne); // should print: oneOne, oneTwo
foo(Values::twoTwo); // should print: twoTwo
3条答案
按热度按时间dsf9zpds1#
如果你有
我建议添加反向查找
std::map
......能够使用
std::map::upper_bound
获得一个迭代器,该迭代器指向您感兴趣的子组之后的第一个元素:Demo
如果你更喜欢在反向查找
std::map
中存储std::string
而不是迭代器,这也能很好地工作:Demo
i34xakig2#
只需将
_map
反转为另一个Map,并使用它来帮助识别哪些"值"是有效的。我稍微修改了代码,在
foo
函数中声明了reverseMap
,但是您可以将reverseMap
的初始化移动到其他地方,使其成为全局变量或成员变量。然后用同样的标准来测试它:
结果:
qnakjoqk3#
_map
已存在,用于“其他”用途,因此无法更改我会选择不完全尊重这项限制,我的理由是,虽然我接受这个前提(”
_map
已经存在,用于“其他”目的”),我不认为它必然暗示结论(“I can 't change that”).可能是当前的用法阻碍了更改,但也可能不是.如果编写其他代码时假定类型为std::unordered_map<std::string, Values>
,那么改变是不可能的。然而,如果代码仅仅假设类型“看起来像什么”,那么改变是可能的。例如,如果有代码使用类似于
那么改变类型是有问题的。但是,一个等价的定义是
并且这种形式不锁定类型。在形式之间的选择可能是代码编写者在编写代码当天的感觉。因此,要求 * 可能 * 比“不能更改”弱。取决于代码是如何编写的,保持“签名兼容”可能就足够了,甚至可能
_map
是一个容器,具有适当的operator[]
来查找字符串就足够了。Boost.Bimap是一个值得考虑的选项,这个容器基本上是一个Map,允许按键或值进行查找,此外,它还允许以不同的方式组织键和值--您可以指定键提供无序(散列)查找,并且值提供有序查找。存在一些功能差异,但是如果你的容器在初始化后不需要修改(看起来是这样),那么许多区别就不相关了。
下面的声明旨在给予如何使用Bimap的概念(未测试;基于Boost的文档和示例)。
这工作得有多好取决于现有代码到底做了什么。左视图与
std::unordered_map<std::string, Values>
签名兼容,所以它可能“只是工作”。一个缺点可能是初始化。看起来你可能需要在函数内初始化,而不是在定义点指定值。
它的一个优点是数据只存储一次,并且没有需要维护的二级数据结构,所以我认为它值得研究。