是否可以检查 C++ std::unordered_map 键中的枚举是否设置了 n 个标志?

问题描述 投票:0回答:1

我正在设置一个 unordered_map,其中键是 Direction 的枚举,定义为:

enum Direction : uint16_t {
    North = 1 << 0,
    East = 1 << 2,
    South = 1 << 3,
    West = 1 << 4,
    None = 1 << 5,
};

目标是检查是否至少设置了 2 个标志,但最多设置了 n 标志。

通过上面定义的枚举,我尝试创建许多 unordered_maps

    std::unordered_map<Direction, std::vector<Tile*>>*      groundTiles;
    std::unordered_map<Direction, std::vector<Tile*>>*      northEastHillTiles;
    std::unordered_map<Direction, std::vector<Tile*>>*      southEastHillTiles;
    std::unordered_map<Direction, std::vector<Tile*>>*      platformTiles;
    std::unordered_map<Direction, std::vector<Tile*>>*      wallTiles;

我将它们初始化为

    groundTiles = new std::unordered_map<Direction, std::vector<Tile*>>();
    groundTiles->insert_or_assign(Direction::None, std::vector<Tile*>());
    groundTiles->insert_or_assign(Direction::East, std::vector<Tile*>());
    groundTiles->insert_or_assign(Direction::West, std::vector<Tile*>());
    groundTiles->insert_or_assign((Direction)(Direction::East|Direction::West),std::vector<Tile*>());

and so on for the other sets

但是,当我尝试从地面(或任何其他集合)拉出一个图块时,我无法检查是否至少设置了 Direction::East 和 Direction::West 。 我试过了:

Tile* westAndEastCapped = southEastHillTiles->at((Direction)(Direction::West | Direction::East)).at(0);

但它似乎只是默认为 Direction::East 设置。

如何从无序地图中选择一个图块,同时设置了东部和西部标志,而没有其他标志?

c++ enums bit-manipulation unordered-map bitflags
1个回答
0
投票

这不是

std::unordered_map::at()
的工作原理。它仅从无序映射中检索与传入参数等于的键的值。相当于“完全”。就是这样。没有别的了。

此外,如果指定的键不存在,

at()
会抛出异常。

std::unordered_map
知道它的关键是它是某种不透明的值。
std::unordered_map
不关心密钥的任何解释或含义,除了
std::unordered_map
对其密钥的唯一要求是它具有相等性比较并且具有哈希函数。

enum
满足这些要求。结束。仅仅因为这个特定的
enum
被解释为某种位掩码,对于
std::unordered_map
来说没有任何意义。

A

std::unordered_map
不太适合您尝试访问其值的方式,它不会起作用。您可能需要为您的值设计一个自定义容器,以有效地实现所需的访问模式。

在最坏的情况下,你总是可以诉诸范围迭代:

for (auto &[key, value]: southEastHillTiles)
{
  // ...
}

然后检查地图中存在的每个

key
,以确定它是否符合您要搜索的内容。这是非常低效的,但这几乎是
unordered_map
可以完成的唯一事情。

© www.soinside.com 2019 - 2024. All rights reserved.