我怎样才能从地图中删除一个元素到一个向量中

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

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

我想通过 <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:

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, because std::all_of returns bool,而不是迭代器。但是 std::remove_if 做你想做的,它删除所有匹配 bool 谓词的实例。

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

第三,内部谓词不应该只是 return std::find_if(returns 迭代器)的结果,而是 return 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();
        }
    );
}