如何将所有子类存储在不同的集合中 C++

How to store all subclasses in different sets c++

我想根据对象的类型来存储对象。 我有一个 Status class 被继承以创建不同的状态,例如 BurnStun 等...

我想将状态存储在集合中,每种类型都有一个集合(一个角色可以一次有多个燃烧状态,所以我想得到一个存储所有燃烧状态但不存储其他状态的集合)。

目前我的解决方案是这样的

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 *"
**

但是这是向下转换,编译器不希望它工作。

我的问题如下:

编辑:

问题是我在上一个代码版本中试图同时做两件事

两个答案都帮助我意识到问题是我试图同时做这两个问题。

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_casting 有未定义的行为。

如果你有很多地方可以投放集合,我很想写一些 _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;

对于您需要的每个演员等等。