在我的实体组件系统中,我使用位掩码来跟踪和查询每个实体具有哪些组件。
// Thanks to Shafik Yaghmour for the macro fix
#define BIT(x) (static_cast<std::uint64_t>(1) << x)
enum class components : std::uint64_t
{
foo = BIT( 0),
bar = BIT( 1),
// Many more omitted
baz = BIT(63)
};
// Operator | is used to build a mask of components. Some entities
// have dozens of components.
auto mask = components::foo | components::bar | components::baz
// Do something with the entity if it has the requisite components.
if ( entity->has_components( mask ) ) { ... }
我已经达到了枚举的64位限制。C++枚举是否可以(可移植地)扩大到超过64位?
更新 1: 我知道 std::bitset
,但是我无法创建像 auto mask = std::bitset<128>{ components::foo, components::baz }
这样的掩码,因为 std::bitset
没有一个可以接受 std::initializer_list
的构造函数。如果您的答案告诉我要使用 std::bitset
,请演示此用法或类似用法。
更新2:我编写了一个函数,可以从std::initializer_list
创建一个std::bitset
:
enum class components : std::size_t
{
foo,
bar,
baz,
count
};
template< typename enumeration, std::size_t bit_count = static_cast< std::size_t >( enumeration::count ) >
std::bitset< bit_count > make_bitset(std::initializer_list< enumeration > list)
{
assert(list.size() <= bit_count);
std::bitset< bit_count > bs{};
for (const auto i : list)
{
bs.set(static_cast< std::size_t >(i));
}
return bs;
}
// Which can create the mask like so:
auto mask = make_bitset< components >( {components::foo, components::baz} );
enum
的值受限于字长,也就是说,它可能限制在16位。 - vonbrand