使用STL find_if时如何在谓词中访问当前检查的元素?
核心错误原因
std::find_if的第三个参数要求传入可调用的谓词,这个谓词会在遍历每个元素时被自动调用,当前遍历到的列表元素会作为参数传入谓词。你之前的写法存在本质问题:
- 直接传入比较表达式的写法不符合接口要求:表达式会在
find_if执行前就完成求值,相当于给算法传了一个固定的布尔值,根本不会在遍历过程中做动态判断 - 表达式里引用的
customer是上下文里提前声明的外部指针,和遍历到的Reservation对象持有的customer指针没有任何关联 - 代码还存在迭代器不匹配问题:遍历取的是
reservation_list的起始迭代器,结束判断却用了res_list的尾迭代器,属于未定义行为
正确实现(C++11及以上版本,推荐写法)
使用lambda表达式作为谓词,lambda的入参就是find_if当前正在检查的列表元素:
#include <algorithm> #include <list> #include <string> // 查找逻辑 const std::string& target_phone = telefonnummer; // 待匹配的目标电话号码 auto find_iter = std::find_if( reservation_list.begin(), reservation_list.end(), [&target_phone](const Reservation& current_res) { // current_res就是当前遍历到的Reservation对象 // 如果customer是Reservation的公有成员指针,可直接写 current_res.customer->get_phone_number() // 如果customer是私有成员,替换成对应getter方法即可 return current_res.get_customer()->get_phone_number() == target_phone; } ); bool found = (find_iter != reservation_list.end());
旧标准兼容写法(C++03)
如果编译器不支持C++11特性,可以自定义谓词结构体实现:
struct MatchResByPhone { std::string target_phone; MatchResByPhone(const std::string& phone) : target_phone(phone) {} // 重载()运算符,让结构体实例可以被调用,入参就是当前遍历到的列表元素 bool operator()(const Reservation& current_res) const { return current_res.get_customer()->get_phone_number() == target_phone; } }; // 查找逻辑 bool found = ( std::find_if( reservation_list.begin(), reservation_list.end(), MatchResByPhone(telefonnummer) ) != reservation_list.end() );
注意:请确保
Reservation里存储的Customer指针不为空,否则调用get_phone_number()会触发空指针崩溃,必要时可以在谓词里先加非空判断。
内容的提问来源于stack exchange,提问作者Franz
相关产品推荐
相关产品推荐

