zip_iterator和lower_bound

时间:2012-11-20 19:31:48

标签: c++ boost iterator lower-bound

我无法弄清楚如何使用lower_bound来调用zip_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&lt; _Myvec&gt;&amp;'”(再加上几十个其他相同的错误),但它与一个模糊的提升有关:: tuple构造函数,而不是给定的lambda。

我做错了什么?

2 个答案:

答案 0 :(得分:3)

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

25.4.3.1 [lower.bound] / p1:

  

要求:: e的元素[first,last)将被分区   尊重表达式e < valuecomp(e, value)

即。只需要*it < v

upper_bound算法具有相反的要求:v < *itequal_range要求两个表达式都有效。

答案 1 :(得分: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解决编译问题。