发布于2026-07-18 阅读(0)
扫一扫,手机访问
C++标准库里的std::adjacent_find,用起来简单,踩坑的地方却不少。很多开发者遇到“查不到重复元素”的问题,第一反应是怀疑容器数据有问题,其实多半是底层逻辑没写对。
默认情况下,std::adjacent_find只检查相邻两个元素是否相等——内部调用的是operator==。如果你的类型不支持这个操作符,或者你想自定义比较逻辑,那就得自己传一个谓词。但问题往往出在这里:谓词的语义是“返回true表示这两个元素满足条件”,而不是“返回true表示它们不同”。常见的错误是把谓词写成a > b,却期望它找到重复值。这实际上是在找“递减对”,而不是“相等对”。
operator==,否则编译报错[](const auto& a, const auto& b) { return a == b; },而不是别的std::vector这类类型,大小写敏感比较需要显式传std::equal_to(),或者自己写一个忽略大小写的lambda
迭代器失效是C++里一个老生常谈的问题,在std::adjacent_find上同样常见。这个函数返回的是正向迭代器,一旦容器发生插入、删除、reserve或resize,这个迭代器就立即失效。最典型的坑是:查到位置后,把它存为裸指针或长期缓存,然后容器被修改了,再用这个迭代器——结果不言而喻。
if (auto it = std::adjacent_find(v.begin(), v.end()); it != v.end()) { /* 处理 *it 和 *(it+1) */ }auto pos = std::adjacent_find(...); v.push_back(x); use(*pos);——此时pos已经无效,解引用是未定义行为it - v.begin()),前提是容器不会重新分配内存从算法本身看,std::adjacent_find是线性遍历,与容器底层无关。但实际性能受迭代器类型影响:std::list的双向迭代器支持++和--,没问题;std::forward_list的前向迭代器只能++,而adjacent_find内部只需要单向移动,所以完全兼容,没有额外开销。
vector、deque、list、forward_list)和关联容器(set等)都可用,只要提供符合要求的迭代器std::array和原始数组也支持,传入arr和arr + N即可forward_list,不能用it + 1,但std::adjacent_find内部用的是std::next(it),已经适配好了另一个常见误区:当容器元素数少于2时,std::adjacent_find直接返回end(),不报错,也不抛异常。新手往往忽略这个前提,直接对返回值做*(it + 1),导致越界。
if (it != container.end())。别用it == container.begin()或it == nullptr,这些都不对end()if (v.size() < 2) { /* 直接返回或处理 */ }真正复杂的地方在于,谓词语义和迭代器生命周期是耦合的——一旦出错,就是静默的未定义行为,不会报错,也不会给你任何提示。最容易被忽略的是:哪怕你只读容器,只要用了std::vector::emplace_back这类可能触发重新分配的操作,之前拿到的迭代器就废了。这些细节,往往比算法本身更需要留意。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8