std::upper_bound возвращает константный итератор в константной функции-члене
Вот класс, который содержит boost::circular_buffer
некоторых struct
, Я делаю typedef для итераторов в содержащийся circular_buffer
,
Моя проблема заключается в следующем: когда doWork
функция помечена const
Возвращаемое значение std::upper_bound
не совместим с MyIterator
тип из-за возвращаемого значения, имеющего boost::cb_details::const_traits
, Если я удалю const
Ключевое слово из функции, все мои ошибки компиляции уходят.
Чтобы было ясно, ошибка компилятора заключается в следующем:
error: conversion from ‘boost::cb_details::iterator<boost::circular_buffer<Wrapper<int>::Sample, std::allocator<Wrapper<int>::Sample> >, boost::cb_details::const_traits<std::allocator<Wrapper<int>::Sample> > >’ to non-scalar type ‘Wrapper<int>::MyIterator {aka boost::cb_details::iterator<boost::circular_buffer<Wrapper<int>::Sample, std::allocator<Wrapper<int>::Sample> >, boost::cb_details::nonconst_traits<std::allocator<Wrapper<int>::Sample> > >}’ requested [](const Sample& a, const Sample& b) { return a.foo < b.foo; });
Вот отдельный пример:
#include <algorithm>
#include <boost/circular_buffer.hpp>
template <typename T>
class Wrapper {
public:
struct Sample {
T foo;
};
typedef typename boost::circular_buffer<Sample>::iterator MyIterator;
Wrapper(int size) { cb.resize(size); }
void add(T val) { cb.push_back(Sample{val}); }
void doWork(T bound) const {
MyIterator iter =
std::upper_bound(cb.begin(), cb.end(), Sample{3},
[](const Sample& a, const Sample& b) { return a.foo < b.foo; });
}
boost::circular_buffer<Sample> cb;
};
int main() {
Wrapper<int> buf(100);
buf.add(1);
buf.add(5);
buf.doWork(3);
return 0;
}
Итак, почему эта функция не может быть const? Почему маркировка const имеет этот побочный эффект? Мне нужен неконстантный итератор в контейнер, но в моем реальном тестовом примере я не собираюсь вообще изменять контейнер.
2 ответа
Тебе понадобится const_iterator
, поскольку вы эффективно соблюдаете const
контейнер.
Может быть:
typedef typename boost::circular_buffer<Sample>::const_iterator MyConstIterator;
... тогда сделай iter
один из них.
Кто-то скажет вам, что вы могли бы избежать этого с auto
, Это правда, но тогда вы бы никогда не обнаружили эту "ошибку", или что const_iterator
есть.
Если ваша функция отмечена const
тогда весь ваш доступ к переменным-членам будет const
тоже.
const
Контейнер позволит только доступ к const_
итераторы, это просто способ работы итераторов.