C++ Vector of shared_ptr of child to vector of shared_ptr to base

sigwle7e  于 2023-05-20  发布在  其他
关注(0)|答案(2)|浏览(135)

我有这门课

class GameObjectTemplateModel : public DatabaseModel<GameObjectTemplate, WorldDatabaseConnection, GameObjectTemplateModel>

我有这个:

std::vector<std::shared_ptr<DatabaseModel>>  ManyWhere(const std::string& column, const std::string& where);

还有这个

std::vector<std::shared_ptr<GameObjectTemplateModel>> LootableCollection;

为什么我不能做:

LootableCollection = ManyWhere("test","test");

我的问题是我怎样才能使子shared_ptrs的vector从base shared_ptr的vector中获取它的数据?
如果我使用dynamic_cast,这是个好主意吗?

z18hc3ub

z18hc3ub1#

这里的问题是,即使可能存在在向量的元素类型之间进行转换的方法,这也没有建立向量类型之间的关系,并且不存在赋值/初始化工作所需的赋值运算符/构造函数。
您需要为此提供自己的转换。根据你是否确定元素的类型是正确的,你应该使用std::static_pointer_cast or std::dynamic_pointer_cast进行元素转换:
下面的示例使用Base作为基类,Derived作为派生类,并假设std::vector<std::shared_ptr<Base>>的所有元素实际引用Derived

struct Base
{
    virtual ~Base() = default;
};

struct Derived : Base
{
};

template<class T, class U>
std::vector<std::shared_ptr<T>> ConvertSharedPointerVector(std::vector<std::shared_ptr<U>>&& from)
{
    std::vector<std::shared_ptr<T>> to;
    to.reserve(from.size());

    for (auto& e : from)
    {
        to.emplace_back(std::static_pointer_cast<T>(std::move(e)));
    }

    return to;
}

std::vector<std::shared_ptr<Base>> Create()
{
    return { std::make_shared<Derived>(), std::make_shared<Derived>() };
}

int main()
{
    std::vector<std::shared_ptr<Derived>> convertedVector = ConvertSharedPointerVector<Derived>(Create());
}

注意:你最好避免这种转换。您可以使用模板来完成此操作。

2skhul33

2skhul332#

我的问题是我怎样才能使子shared_ptrs的vector从base shared_ptr的vector中获取它的数据?
你需要有一些东西,将转换每个指针依次。在C++23中,它可以是像std::ranges::to<std::vector>这样的视图。

LootableCollection = ManyWhere("test","test") | std::ranges::to<std::vector>;

在此之前,您可以使用迭代器赋值(带有一个帮助变量)

auto collection = ManyWhere("test","test");
LootableCollection.assign(collection.begin(), collection.end());

如果我使用dynamic_cast是个好主意吗?
不。使用通过dynamic_cast获取的指针在几乎所有情况下都是未定义的行为,这也不是例外。
类型std::vector<std::shared_ptr<GameObjectTemplateModel>>与类型std::vector<std::shared_ptr<DatabaseModel>>完全不相关,尽管类型GameObjectTemplateModelDatabaseModel相关。

相关问题