You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++类对象向量中最值间元素迁移与原向量移除实现疑问

C++新手问题:筛选并移动Vector中Ball对象的中间元素

我是C++新手,现有程序可找出Ball类对象vector中按size字段排序的minBall和maxBall,需将size介于两者之间的所有元素移至另一个vector,并从原vector中移除这些元素。我无法理清如何用迭代器遍历vector并判断条件(it > minVal && it < maxVal)。

我的Ball类实现

class Ball {
private:
    int size;
    std::string color;

public:
    Ball() :size(0), color("") {};
    Ball(int size, std::string color) : size(size), color(color) {}
    int get_size() { return size; }
    std::string get_color() { return color; }

    // перегрузка операторів для зручності роботи 
    bool operator<(const Ball& other) { return size < other.size; }  
    bool operator>(const Ball& other) { return size > other.size; }  
    friend std::ostream& operator<<(std::ostream& os, const Ball& ball) { // дружня ф-ція перегрузки оператора "<< для виводу всіх полів
        os <<  ball.size << "\\" << ball.color;
        return os;
    }
};

我的尝试

我已有函数可得到两个类对象:minBall和maxBall(按size字段)。我尝试使用std::find_if()并编写了基础比较器:

bool comparator_for_ext(Ball& a, Ball& minBall, Ball& maxBall) {
    return a < maxBall && a > minBall;
}

但不知道如何向comparator_for_ext()传递参数,即std::find_if(balls.begin(), balls.end(), comparator_for_ext(这里该填啥, minBall, maxBall))中的参数该如何填写?


解决方法

std::find_if()的第三个参数要求是仅接受单个参数的可调用对象(如函数指针、Lambda表达式、仿函数),你的比较器有三个参数,不符合要求,因此不能直接传入。下面是两种简单可行的实现方式:

方法1:使用Lambda表达式(推荐,简洁直观)

Lambda可以直接捕获外部的minBall和maxBall,无需单独编写比较函数,同时可以直接完成遍历、移动和删除操作:

// 假设原vector为balls,目标vector为middleBalls
auto it = balls.begin();
while (it != balls.end()) {
    if (*it > minBall && *it < maxBall) {
        // 将元素移动到目标vector(避免拷贝,提升效率)
        middleBalls.push_back(std::move(*it));
        // erase返回下一个有效迭代器,无需手动++
        it = balls.erase(it);
    } else {
        ++it;
    }
}

如果追求更高效率,可以结合std::partition和移动迭代器:

// 将所有中间元素移到原vector末尾
auto partitionIt = std::partition(balls.begin(), balls.end(),
    [&minBall, &maxBall](const Ball& b) {
        return b > minBall && b < maxBall;
    });
// 批量移动中间元素到目标vector
middleBalls.insert(middleBalls.end(),
    std::make_move_iterator(partitionIt),
    std::make_move_iterator(balls.end()));
// 从原vector移除中间元素
balls.erase(partitionIt, balls.end());

方法2:用std::bind适配现有比较函数

如果坚持使用自己编写的comparator_for_ext,可以用std::bind将minBall和maxBall绑定为固定参数,转换为单参数可调用对象:

#include <functional> // 必须包含此头文件

// 先修改比较函数参数为const引用,避免不必要的拷贝
bool comparator_for_ext(const Ball& a, const Ball& minBall, const Ball& maxBall) {
    return a < maxBall && a > minBall;
}

// 使用时的写法
auto it = std::find_if(balls.begin(), balls.end(),
    std::bind(comparator_for_ext, std::placeholders::_1, minBall, maxBall));

不过这种写法不如Lambda直观,新手优先推荐Lambda方案。


额外优化建议

  • 你的Ball类重载的operator<和operator>应添加const修饰,确保可以比较const对象:
bool operator<(const Ball& other) const { return size < other.size; }  
bool operator>(const Ball& other) const { return size > other.size; }  
  • get_size()和get_color()也建议添加const,符合C++的const正确性原则:
int get_size() const { return size; }
std::string get_color() const { return color; }

内容的提问来源于stack exchange,提问作者Garry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 09:35:20