3

我不知道如何lower_boundzip_iterator.

这不会编译:

#include <boost/iterator/zip_iterator.hpp>
#include <vector>
#include <algorithm>

void main()
{
    typedef int Key;
    typedef double Value;

    typedef boost::tuple<typename std::vector<Key>::iterator,
                         typename std::vector<Value>::iterator> the_iterator_tuple;
    typedef boost::zip_iterator<the_iterator_tuple> the_zip_iterator;

    std::vector<Key>   keys_;
    std::vector<Value> values_;

    // Add values to keys_ and values_...

    auto it = std::lower_bound(
        the_zip_iterator(the_iterator_tuple(keys_.begin(), values_.begin())),
        the_zip_iterator(the_iterator_tuple(keys_.end(), values_.end())),
        123,
        [](const the_iterator_tuple & it, const int v) -> bool { return *boost::get<0>(it) < v; }
    );

    // Use "it"...
}

VS2010 说它“无法将参数 1 从 'int' 转换为 'const std::_Vector_iterator<_Myvec> &'”(加上其他几十个相同的错误),但它与一个不起眼的 boost::tuple 构造函数有关,而不是给定的 lambda。

我究竟做错了什么 ?

4

2 回答 2

3

这看起来像 VS2010 中的“概念检查”错误。

25.4.3.1 [下限]/p1:

Requires:: 的元素e[first,last)根据表达式e < valueor进行分区comp(e, value)

即只*it < v需要。

upper_bound算法有相反的要求: v < *it. 并且equal_range需要这两个表达式才能工作。

于 2012-11-20T20:24:57.793 回答
2

std::lower_bound(it, end, v)需要能够同时做到*it < vv < *it。您的函数对象仅支持其中之一。

既然对此有评论,就留下上面的说法:事实并非如此。正如霍华德所指出的,比较需要使用comp(*it, v),即这个操作不需要是对称的。

但是,查看它的文档boost::zip_iterator<It0, It1>似乎会*it产生一个boost::tuple<typename It0::reference, typename It1::reference>. 因此,添加typedef

typedef boost::tuple<typename std::vector<Key>::reference,
                     typename std::vector<Value>::reference> the_reference_tuple;

...并将 lambda 更改为

[](the_reference_tuple const& it, int v) { return it.get<0>() < v; }

使用 gcc 和 clang 解决编译问题。

于 2012-11-20T20:14:51.583 回答