首页 > 解决方案 > 从向量中删除 unique_ptr 的问题

问题描述

我正在努力从向量中删除 unique_ptr 。我有一个向量:

std::vector<std::unique_ptr<Agent>>;

我正在填写一定数量的特工。我通过以下方式进行操作:

在类构造函数列表中:

agentsVec(std::accumulate(agentsQuantity.begin(), agentsQuantity.end(), 0, 
                           [](int value, const QuantityMap::value_type& p) { return value + p.second; }))

在负责生成代理的函数中:

auto agentVecIter = agentsVec.begin();
    std::for_each(agentsQuantity.begin(), agentsQuantity.end(), [this, &agentVecIter](const QuantityMap::value_type& p)
    {
        std::generate_n(agentVecIter, p.second, [this, &p]()
        {
            auto agent = factory.createAgent(p.first);
            changeAgentOnLattice(generatePosition(), agent->getID());
            return agent;
        });
        std::advance(agentVecIter, p.second);
    });

agentQuantity 是表示某种类型的代理数量的映射。代理工厂返回 std::unique_ptr;

在程序期间,可能需要根据它的 ID 从向量中删除一些代理(然后将代理的 ID 返回到 freeID 的堆栈)。

杀代理:

std::experimental::erase_if(agentsVec, [this, &positionID](auto const& agent) { 
    auto agentID = agent->getID();
    if (positionID == agentID) {
        Utils::addIDToStack(agentID);
        return true;
    }
    return false;
});

为了测试这一点,我添加了 5 个将被“杀死”的代理。在大约 40% 的情况下,我得到了:

调试断言失败!向量迭代器不可解引用

我究竟做错了什么?

编辑:更多代码进行澄清。代理点阵(包含agentsVec)是在Environment 类中创建的。然后环境进入无限循环并遍历晶格中的所有位置并检查那里是否存在某些东西。如果是 -> 它会移动代理并更新其运行状况:

环境::健康更新:

for (int i = 0; i < latticeSize; i++) {
    for (int j = 0; j < latticeSize; j++) {
        if (lattice->getAgentID(Position(i, j))) {
            Agent* currentAgent = lattice->getAgentInstance(Position(i, j));
            currentAgent->updateHealth();
            if (currentAgent->getAgentType() == Enums::AgentType::Predator && currentAgent->getHealth() <= -10) {
                lattice->killAgent(Position(i, j));
            }
        }
    }
}

Lattice::移动代理:

const auto originRow = Utils::BoundaryCondition(origin.first, latticeSize);
    const auto originCol = Utils::BoundaryCondition(origin.second, latticeSize);
    const auto destRow = Utils::BoundaryCondition(destination.first, latticeSize);
    const auto destCol = Utils::BoundaryCondition(destination.second, latticeSize);

    if (getAgentID(origin) == static_cast<int>(Enums::AgentType::Field)) {
        Logger::getInstance().Log("lattice", "\tCannot move - there is no moving creature on origin position");
        return false;
    }

    if (getAgentID(destination) != static_cast<int>(Enums::AgentType::Field)) {
        Logger::getInstance().Log("lattice", "\tCannot move - destination position is occupied");
        return false;
    }

    latticeMap[destRow][destCol] = static_cast<int>(getAgentID(origin));
    latticeMap[originRow][originCol] = static_cast<int>(Enums::AgentType::Field);
    Logger::getInstance().Log("lattice", "\tMoved succesfully");

    return true;

Agent getter(在 Environment 中用于从 Lattice::agentsVec 获取 Agent 指针)

Agent* Lattice::getAgentInstance(Position position) {
    int ID = getAgentID(position);
    auto it = std::find_if(std::execution::par, agentsVec.begin(), agentsVec.end(),
        [=](std::unique_ptr<Agent>& agent) { return agent->getID() == ID; });
    if (it != agentsVec.end()) {
        return it->get();
    }
    return nullptr;
}

和 AgentType 吸气剂:

Enums::AgentType Lattice::checkAgentType(int ID)
{
    auto it = std::find_if(std::execution::par, agentsVec.begin(), agentsVec.end(), 
    [=](std::unique_ptr<Agent>& agent)  { return agent->getID() == ID; });

    if(it != agentsVec.end()) {
        return it->get()->getAgentType();
    }
    return Enums::AgentType::Unknown;
}

标签: c++vectorunique-ptrerase-remove-idiom

解决方案


推荐阅读