如何向std::lower_bound()的比较函数传递迭代器?
解决办法:不用自定义容器/重写lower_bound实现需求
嘿,你不想自定义容器或重写std::lower_bound的话,有几个实用的方案能让你在比较器里拿到迭代器,不用传值类型直接操作:
方案1:针对连续内存容器的地址反向计算法
如果你的容器是连续内存存储的(比如std::vector、std::array),可以通过元素的地址反向算出对应的迭代器,完全不用额外封装:
#include <vector> #include <algorithm> #include <iostream> int main() { std::vector<int> nums = {2, 4, 6, 8, 10}; int target = 7; // 捕获容器的起始迭代器 auto start_it = nums.begin(); auto comp = [&start_it](int val, const int& elem) { // 通过元素地址计算当前迭代器 auto current_it = start_it + (&elem - &*start_it); // 在这里查看/记录迭代器信息 std::cout << "正在检查迭代器,指向元素:" << *current_it << ",位置索引:" << std::distance(start_it, current_it) << "\n"; // 原有的比较逻辑 return val < elem; }; auto result = std::lower_bound(nums.begin(), nums.end(), target, comp); return 0; }
优点:代码极简,不需要额外的类或适配器;
缺点:仅适用于连续内存容器,像std::list、std::map这类非连续容器无法使用。
方案2:通用迭代器包装器(适配所有容器)
如果需要支持所有类型的容器,可以写一个超轻量的迭代器包装器,把迭代器和元素值打包返回,这样比较器就能直接拿到迭代器:
#include <vector> #include <algorithm> #include <utility> #include <iostream> // 简单的迭代器包装器,解引用返回(迭代器, 元素值)的pair template <typename Iter> struct IteratorWrapper { using value_type = std::pair<Iter, typename Iter::value_type>; using reference = const value_type&; using iterator_category = typename Iter::iterator_category; using difference_type = typename Iter::difference_type; Iter inner_it; explicit IteratorWrapper(Iter it) : inner_it(it) {} reference operator*() const { static value_type temp; temp = {inner_it, *inner_it}; return temp; } IteratorWrapper& operator++() { ++inner_it; return *this; } IteratorWrapper operator++(int) { auto temp = *this; ++inner_it; return temp; } bool operator!=(const IteratorWrapper& other) const { return inner_it != other.inner_it; } }; // 辅助函数,简化包装器的创建 template <typename Iter> IteratorWrapper<Iter> wrap_iterator(Iter it) { return IteratorWrapper<Iter>(it); } int main() { std::vector<int> nums = {1, 3, 5, 7, 9}; int target = 6; auto comp = [](int val, const auto& elem_pair) { // elem_pair.first 就是当前的迭代器 auto& current_it = elem_pair.first; std::cout << "正在检查迭代器,指向元素:" << *current_it << "\n"; // 原有的比较逻辑 return val < elem_pair.second; }; // 用包装后的迭代器调用lower_bound auto wrapped_result = std::lower_bound(wrap_iterator(nums.begin()), wrap_iterator(nums.end()), target, comp); // 转换回原迭代器 auto result = wrapped_result.inner_it; return 0; }
优点:适用于所有标准容器的迭代器,完全通用;
缺点:需要写几行包装器代码,但代码量很小且复用性高。
这两个方案都避开了你不想做的自定义容器或重写std::lower_bound的工作,完全基于标准库扩展实现需求~
内容的提问来源于stack exchange,提问作者sigil
相关产品推荐
相关产品推荐

