I can’t figure out how to call lower_bound with a zip_iterator.
This won’t compile:
#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 says it “cannot convert parameter 1 from ‘int’ to ‘const std::_Vector_iterator<_Myvec> &'” (plus several dozen other things for the same error), but it has to do with an obscure boost::tuple constructor, not with the given lambda.
What am I doing wrong ?
std::lower_bound(it, end, v)needs to be able to do both*it < vandv < *it. Your function object supports only one of these.Since there is a comment on this, leaving the above statement: This isn’t the case. As Howard pointed out, the comparison is required to use
comp(*it, v), i.e., there is no need for this operation to be symmetric.However, looking at the documentation of
boost::zip_iterator<It0, It1>it seems that*ityields aboost::tuple<typename It0::reference, typename It1::reference>. Thus, adding thetypedef… and changing the lambda to become
solves the compilation issues using gcc and clang.