如何将迭代器传递到std :: lower_bound()比较函数

How to to pass iterators to the std::lower_bound() comparison function?

本文关键字:lower bound 函数 比较 std 迭代器      更新时间:2023-10-16

在以下从cplusplus.com借来的声明中

template<class ForwardIterator, class T, class Compare>
ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T& val, Compare comp);

comp()应该类似于这样:

template<class T>
bool comp(const T& v1, const T& v2);

问题是我不想在那里传递值类型。我想将迭代器传递给它,然后将它们移动好吧,只需在签发之前默默地凝视它们。(更不用说 - 记录他们。(是否有任何解决方法?

当然,我可以用自己的迭代器编写自己的容器类,当然可以编写自己的std::lower_bound()实现。这两个选项都令人不愉快。

来自 std::lower_bound doc,可以读取 bool comp(const Type1 &a, const Type2 &b);

Type1类型必须使ForwardIt类型的对象被删除,然后隐式转换为Type1Type2类型必须使T类型的对象可以隐式转换为Type2

这意味着,std::lower_bound将始终将comp与范围内的元素称为左手侧参数,而value将CC_14作为右手侧参数。如果您的搜索范围是连续范围(这意味着您正在处理std::vectorstd::arraystd::valarraystd::string,...或C-Style阵列(,则可以从范围的开始和comp'S之间的距离设计一个迭代器左手参数:

auto v = std::vector<int>{0, 1, 2, 3, 4, 5};
auto comp = [&v](const int &lhs, const int &rhs)
{
    auto it_lhs = cbegin(v) + std::distance(std::addressof(*cbegin(v)), &lhs);
    return *it_lhs < rhs;
};
std::cout << *std::lower_bound(begin(v), end(v), 2, comp) << "n";

来自doc:

谓词函数的签名应等效于 以下:

comp()0

签名不需要具有const &,但是该功能不得 修改传递给它的对象。

这样您就不能,不应该这样做。std::lower_bound具有特定的目的,并且不应以任何方式修改输入。为此目的编写自己的功能。


如果您仅需要索引,并且您的容器将其元素存储在线性,连续的内存块中,则可以执行此操作(例如,使用std::vector(:

std::vector<...> vec;
...
const auto* firstElemPtr = &vec[0];
std::lower_bound(vec.begin(), vec.end(), key, [firstElemPtr](const auto& left, const auto& right) -> bool {
  size_t index = &left - firstElemPtr;
  // now do the comparison
});