Я не могу понять, как позвонить 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<_Myvec> &'»(плюс несколько десятков других вещей для той же ошибки), но это связано с неясным конструктором boost :: tuple, а не с данной лямбда-выражением.
Что я делаю неправильно ?
std::lower_bound(it, end, v)
должен быть в состоянии сделать оба *it < v
а также v < *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;
… и изменяя лямбду, чтобы стать
[](the_reference_tuple const& it, int v) { return it.get<0>() < v; }
решает проблемы компиляции, используя gcc и clang.
Это похоже на «проверку концепции» в VS2010.
25.4.3.1 [lower.bound] / p1:
Требуется :: Элементы
e
из[first,last)
должен быть разделен с
уважение к выражениюe < value
или жеcomp(e, value)
,
То есть только *it < v
необходимо.
upper_bound
Алгоритм имеет противоположное требование: v < *it
, А также equal_range
требует, чтобы оба выражения работали.