如何将元素从地图中删除到向量中

How can i delete an element from a map into a vector

本文关键字:删除 向量 地图 元素      更新时间:2024-04-28

我目前正在尝试一个游戏项目,以消除飞机在到达预定到达的航站楼之前坠毁时的悬挂参考。

我只想浏览<algorithm>函数,以便更好地了解它们是如何工作的。

目前,我已经尝试浏览包含与终端相关联的所有平面的地图,将其与所有平面的列表进行比较,并检查地图中的平面是否不再在矢量中,然后将其从地图中删除以释放相关联的终端。

void remove_crashed_aircraft(std::unordered_map<const Aircraft*, size_t>& reserved_terminals, std::vector<std::unique_ptr<Aircraft>>& aircrafts)
{
auto it = std::all_of(reserved_terminals.begin(), reserved_terminals.end(), 
[aircrafts](const Aircraft* a1){ return std::find_if(aircrafts.begin(), aircrafts.end(),
[a1](std::unique_ptr<Aircraft> a2){ return a1==a2.get();});});

reserved_terminals.erase(it);
}

这是我的飞机等级:

class Aircraft : public GL::Displayable, public GL::DynamicObject
{
private:
const AircraftType& type;
const std::string flight_number;
Point3D pos, speed; // note: the speed should always be normalized to length 'speed'
WaypointQueue waypoints = {};
Tower& control;
bool landing_gear_deployed = false; // is the landing gear deployed?
bool is_at_terminal        = false;
int fuel                   = 0;
// turn the aircraft to arrive at the next waypoint
// try to facilitate reaching the waypoint after the next by facing the
// right way to this end, we try to face the point Z on the line spanned by
// the next two waypoints such that Z's distance to the next waypoint is
// half our distance so: |w1 - pos| = d and [w1 - w2].normalize() = W and Z
// = w1 + W*d/2
void turn_to_waypoint();
void turn(Point3D direction);
// select the correct tile in the plane texture (series of 8 sprites facing
// [North, NW, W, SW, S, SE, E, NE])
unsigned int get_speed_octant() const;
// when we arrive at a terminal, signal the tower
void arrive_at_terminal();
// deploy and retract landing gear depending on next waypoints
void operate_landing_gear();
void add_waypoint(const Waypoint& wp, const bool front);
bool is_on_ground() const { return pos.z() < DISTANCE_THRESHOLD; }
float max_speed() const { return is_on_ground() ? type.max_ground_speed : type.max_air_speed; }
bool is_paused = false;
Aircraft(const Aircraft&) = delete;
Aircraft& operator=(const Aircraft&) = delete;
public:
Aircraft(const AircraftType& type_, const std::string_view& flight_number_, const Point3D& pos_,
const Point3D& speed_, Tower& control_, int fuel_) :
GL::Displayable { pos_.x() + pos_.y() },
type { type_ },
flight_number { flight_number_ },
pos { pos_ },
speed { speed_ },
control { control_ },
fuel { fuel_ }
{
speed.cap_length(max_speed());
}
const std::string& get_flight_num() const { return flight_number; }
float distance_to(const Point3D& p) const { return pos.distance_to(p); }
bool is_circling() const 
{
if (!has_terminal() && !is_at_terminal)
{
return true;
}
return false;
}
bool has_terminal() const 
{ 
if (waypoints.empty())
{
return false;
}
else
{
return waypoints.back().type == wp_terminal;
} 
}
bool is_low_on_fuel() const 
{
if (fuel<200)
{
return true;
}
else
{
return false;
}
}
void display() const override;
bool move() override;
void refill(int& fuel_stock);
friend class Tower;
friend class AircraftManager;
};

不幸的是,函数的代码产生了我无法理解的错误。

use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Aircraft; _Dp = std::default_delete<Aircraft>]’
static assertion failed: result type must be constructible from value type of input range

如果有人知道我该如何做到这一点,我将不胜感激!

首先,必须使用std::remove_if,因为std::all_of返回bool,而不是迭代器。但是std::remove_if可以执行您想要的操作,它会删除所有与布尔谓词匹配的实例。

其次,出现编译错误是因为到处都是按值传递的,所以不是(std::unique_ptr<Aircraft> a2)传递引用(std::unique_ptr<Aircraft> const & a2),而是[aircrafts][a1]传递[&aircrafts][&a1]

第三,内部谓词不应该只返回std::find_if(返回迭代器(的结果,而应该返回bool,即将find_if的结果与aircrafts.end()进行比较。

在速度方面,如果需要,可以优化您的算法,为此,您必须将std::vector转换为std::unordered_set,然后遍历第一个映射并检查第二个映射中的包含性。如果你没有太多的元素,速度也不重要,那么你的算法就可以了。

最终工作代码如下:

void remove_crashed_aircraft(
std::unordered_map<const Aircraft*, size_t>& reserved_terminals,
std::vector<std::unique_ptr<Aircraft>>& aircrafts
) {
std::remove_if(reserved_terminals.begin(), reserved_terminals.end(), 
[&aircrafts](auto const & a1){
return std::find_if(aircrafts.begin(), aircrafts.end(),
[&a1](auto const & a2){ return a1.first == a2.get(); })
== aircrafts.end();
}
);
}