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
相关产品推荐
相关产品推荐

