如何将所有子类存储在不同的集合中 C++
How to store all subclasses in different sets c++
我想根据对象的类型来存储对象。
我有一个 Status
class 被继承以创建不同的状态,例如 Burn
、Stun
等...
我想将状态存储在集合中,每种类型都有一个集合(一个角色可以一次有多个燃烧状态,所以我想得到一个存储所有燃烧状态但不存储其他状态的集合)。
目前我的解决方案是这样的
std::map<std::type_index, std::set<Status*>> statuses;
// access all Burn statuses
for (const Burn* b : statuses.find(typeid(Burn))->second) {} // error : E0144 a value of type "Status *" cannot be used to initialize an entity of type "const DamageModifier *"
**
但是这是向下转换,编译器不希望它工作。
我的问题如下:
- 如何在不复制的情况下访问集合并将其向下转换为正确的类型
- 你有没有想过任何其他方式来存储同一子类型的所有状态并且易于访问?
- 我不想将它全部存储在一组动态演员中,因为它开始变得昂贵
- 我不想为每个新
Status
subclass. 手动申报一套
编辑:
问题是我在上一个代码版本中试图同时做两件事
- 从
std::set<Status*>
切换到 std::map<std::typeid, std::set<Status*>>
只要你的结果和以前一样就可以了
- 试图隐式转换一整套无用且幼稚的指针,至少在这种情况下是这样
两个答案都帮助我意识到问题是我试图同时做这两个问题。
How could I access a set and downcast it to the right type without copying
你可以使用static_cast
向下转换:
for (const Status* s : statuses.find(typeid(Burn))->second) {
auto b = static_cast<const Burn*>(s);
}
您必须非常小心,不要将指向错误派生 类 的指针插入到错误的集合中。这将默默地通过编译并在运行时中断(如果你幸运的话)。
你需要在某处进行演员表。如果您通过例如将插入 statuses
门控void add_status(Status * status) { statuses[typeof(status)].insert(status); }
,那么你可以安全地 static_cast
,否则你必须小心,因为不正确的 static_cast
ing 有未定义的行为。
如果你有很多地方可以投放集合,我很想写一些 _view_cast
模板。
template <typename To>
struct static_view_cast_t
{
template <std::ranges::view View>
auto operator()(View view) {
return view | std::ranges::views::transform([](auto & from) -> To { static_cast<To>(from); });
}
template <std::ranges::view View>
friend auto operator|(View view, static_view_cast_t c) {
return c(view);
}
};
template <typename To>
constexpr static_view_cast_t static_view_cast;
对于您需要的每个演员等等。
我想根据对象的类型来存储对象。
我有一个 Status
class 被继承以创建不同的状态,例如 Burn
、Stun
等...
我想将状态存储在集合中,每种类型都有一个集合(一个角色可以一次有多个燃烧状态,所以我想得到一个存储所有燃烧状态但不存储其他状态的集合)。
目前我的解决方案是这样的
std::map<std::type_index, std::set<Status*>> statuses;
// access all Burn statuses
for (const Burn* b : statuses.find(typeid(Burn))->second) {} // error : E0144 a value of type "Status *" cannot be used to initialize an entity of type "const DamageModifier *"
**
但是这是向下转换,编译器不希望它工作。
我的问题如下:
- 如何在不复制的情况下访问集合并将其向下转换为正确的类型
- 你有没有想过任何其他方式来存储同一子类型的所有状态并且易于访问?
- 我不想将它全部存储在一组动态演员中,因为它开始变得昂贵
- 我不想为每个新
Status
subclass. 手动申报一套
编辑:
问题是我在上一个代码版本中试图同时做两件事
- 从
std::set<Status*>
切换到std::map<std::typeid, std::set<Status*>>
只要你的结果和以前一样就可以了 - 试图隐式转换一整套无用且幼稚的指针,至少在这种情况下是这样
两个答案都帮助我意识到问题是我试图同时做这两个问题。
How could I access a set and downcast it to the right type without copying
你可以使用static_cast
向下转换:
for (const Status* s : statuses.find(typeid(Burn))->second) {
auto b = static_cast<const Burn*>(s);
}
您必须非常小心,不要将指向错误派生 类 的指针插入到错误的集合中。这将默默地通过编译并在运行时中断(如果你幸运的话)。
你需要在某处进行演员表。如果您通过例如将插入 statuses
门控void add_status(Status * status) { statuses[typeof(status)].insert(status); }
,那么你可以安全地 static_cast
,否则你必须小心,因为不正确的 static_cast
ing 有未定义的行为。
如果你有很多地方可以投放集合,我很想写一些 _view_cast
模板。
template <typename To>
struct static_view_cast_t
{
template <std::ranges::view View>
auto operator()(View view) {
return view | std::ranges::views::transform([](auto & from) -> To { static_cast<To>(from); });
}
template <std::ranges::view View>
friend auto operator|(View view, static_view_cast_t c) {
return c(view);
}
};
template <typename To>
constexpr static_view_cast_t static_view_cast;
对于您需要的每个演员等等。