在以下来自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);
问题是我不想在那里传递值类型。我想将迭代器传递给它,然后移动它们好吧,在解除引用之前,只需在comp()
内静静地盯着它们。 (更不用说 - 记录它们。)有没有解决方法呢?
当然,我可以使用自己的迭代器编写自己的容器类,当然我可以编写自己的std::lower_bound()
实现。两种选择都相当不愉快。
答案 0 :(得分:1)
从std::lower_bound
doc,您可以阅读bool comp(const Type1 &a, const Type2 &b);
:
类型
Type1
必须使ForwardIt
类型的对象可以取消引用,然后隐式转换为Type1
。类型Type2
必须使T
类型的对象可以隐式转换为Type2
。
这意味着,std::lower_bound
将始终使用范围中的元素作为左侧参数调用comp
,并将value
作为右侧参数。如果您的搜索范围是连续的范围(意味着您正在处理std::vector
,std::array
,std::valarray
,std::string
,...或C风格的数组),你可以从范围的开始和comp
的左侧参数之间的距离设计一个迭代器:
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";
答案 1 :(得分:0)
来自the doc:
谓词函数的签名应该等同于 以下内容:
bool pred(const Type1 &a, const Type2 &b);
签名不需要
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
});