在我的实体组件系统中,我使用位掩码跟踪和查询每个实体具有哪些组件.
// 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 ) ) { ... }
Run Code Online (Sandbox Code Playgroud)
我达到了枚举的64位限制.C++枚举(可移植)是否可以大于64位?
更新1:我知道std::bitset,但我不能创建一个掩码,auto mask = std::bitset<128>{ components::foo, components::baz }因为std::bitset没有一个构造函数需要一个std::initializer_list.如果您的回答告诉我使用,std::bitset请证明此用法或类似用途.
更新2:我修改了一个函数来创建一个std::bitset来自std::initializer_list:
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} );
Run Code Online (Sandbox Code Playgroud)
正如其他人所说,存储必须是a std::bitset.但是如何将它与枚举接口?使用此答案中概述的运算符重载.枚举器只需要存储位索引号,这会给你带来更多的空间;).
注意,该代码必须被移除操作,即:
flag_bits( t bit ) // implicit
{ this->set( static_cast< int >( bit ) ); }
Run Code Online (Sandbox Code Playgroud)