Я борюсь с удалением 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);
});
agentsQuantity - это карта, которая обозначает количество агентов определенного типа. Фабрика агентов возвращает std :: unique_ptr;
Во время выполнения программы может возникнуть необходимость в удалении какого-либо агента из вектора на основе его идентификатора (идентификатор агента затем возвращается в стек 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% случаев я получил:
Ошибка отладочного подтверждения! Итератор вектора не разыменовывается
Что я делаю не так?
РЕДАКТИРОВАТЬ: больше кода для уточнения. Решетка агентов (которая содержит agentVec) создается в классе 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));
}
}
}
}
Решетка :: Перемещение агента:
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;
Получение агента (используется в Среде для получения указателя агента из Lattice :: agentsVec)
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;
}