在存储Person指针的vector中使用lower_bound插入元素的编译问题
解决
lower_bound插入Person*到vector的编译问题 首先,你的代码编译失败主要有两个核心原因:
Person类缺少匹配的构造函数:你尝试用new Person(name, surname, email)创建对象,但原Person类只声明了成员变量,没有定义接受这三个字符串参数的构造函数,编译器找不到对应的构造方法。lower_bound缺少自定义比较规则:默认情况下,lower_bound会用<运算符比较元素,但Person*的默认比较是指针地址的比较,这不是你需要的按email或姓名排序的逻辑,编译器无法自动推导你想要的比较规则,因此报错。
下面是完整的修复方案:
第一步:完善Person类的构造函数
先给Person类添加一个接受name、surname、email的构造函数,确保能正确创建对象:
class Person { public: string email, name, surname; // 添加构造函数,用std::move优化字符串传递效率 Person(string n, string s, string e) : name(std::move(n)), surname(std::move(s)), email(std::move(e)) {} };
第二步:实现Bus类的Add方法,为lower_bound提供比较谓词
lower_bound需要一个谓词(函数或lambda)来定义两个Person*的比较逻辑,我们分别为按email排序和按姓名排序的vector提供对应的规则:
class Bus { public: vector<Person *> sortedbyemail; vector<Person *> sortedbyname; bool Add(string name, string surname, string email) { // 创建Person对象(现在构造函数存在,不会报错) Person *p = new Person(std::move(name), std::move(surname), std::move(email)); // 1. 插入到sortedbyemail的正确位置:按email升序 auto email_it = lower_bound( sortedbyemail.begin(), sortedbyemail.end(), p, // lambda表达式:比较两个Person*的email字段 [](const Person* a, const Person* b) { return a->email < b->email; } ); sortedbyemail.insert(email_it, p); // 2. 插入到sortedbyname的正确位置:先按name升序,name相同则按surname升序 auto name_it = lower_bound( sortedbyname.begin(), sortedbyname.end(), p, [](const Person* a, const Person* b) { if (a->name != b->name) { return a->name < b->name; } return a->surname < b->surname; } ); sortedbyname.insert(name_it, p); return true; } // 推荐添加析构函数释放内存,避免内存泄漏 ~Bus() { // 两个vector指向同一个Person对象,只需在其中一个遍历删除即可 for (auto person : sortedbyemail) { delete person; } sortedbyname.clear(); } };
关键说明
- 自定义比较谓词:lambda表达式明确告诉
lower_bound如何判断两个Person*的顺序,这样它才能找到第一个大于等于当前元素的位置,保证vector始终有序,无需后续排序。 - 避免重复删除:因为两个vector都存储了同一个
Person*的指针,析构函数只需要在其中一个vector遍历删除,否则会导致双重释放内存的错误。 std::move优化:传递字符串参数时用std::move可以避免不必要的字符串拷贝,提升代码性能。
这样修改后,你的Add方法就能正常编译,并且每次插入都会把Person*放到vector的正确位置,保持容器有序。
内容的提问来源于stack exchange,提问作者Čeněk Sůva
相关产品推荐
相关产品推荐

