Перебор коллекции с помощью const_iterator в функции, объявленной как const, приводит к ошибке

Этот метод:

void LRU::displayQueue() const
{
for(iter = m_buffer.begin(); iter != m_buffer.end(); ++iter)
std::cout << (*iter) << " ";
std:: cout << std::endl;
}

приводит к следующей ошибке:

lru.cpp:58: error: passing 'const std::_Deque_iterator<int, const int&, const int*>' as    'this' argument of 'std::_Deque_iterator<int, const int&, const int*>& std::_Deque_iterator<int, const int&, const int*>::operator=(const std::_Deque_iterator<int, const int&, const int*>&)' discards qualifiers

m_buffer а также iter объявлены в моем заголовочном файле, где буфер объявлен как deque типа int а также iter постоянный итератор:

// ...

std::deque<int> m_buffer;
std::deque<int>::const_iterator iter;

// ...

Удаление const в displayQueue Метод устранит ошибку компилятора, но так как эта функция не должна изменять какие-либо данные в dequeЯ хочу сделать это явным, сохраняя мой код «const-correct». Почему это может привести к ошибке, когда мой итератор const_iterator?

1

Решение

Вы изменяете объект, устанавливая значение переменной-члена const итератора, тем самым лишая законной силы ограничение вашей функции. Используйте локальную переменную.

const_iterator только означает, что итератор не может изменить последовательность, но вы не изменяете последовательность, вы изменяете переменную-член итератор сам.

1

Другие решения

Вы не можете изменить ни одного члена класса в const метод member, и вот что вы пытаетесь сделать здесь:

for(iter = m_buffer.begin();iter != m_buffer.end(); ++iter)
^^^^^^^                                         ^^^^^^

iter является членом class LRU, поэтому вы не можете назначить, увеличить или иным образом изменить его в const функция-член.

Одним из решений было бы сделать iter изменяемые:

mutable std::deque<int>::const_iterator iter;

Но я чувствую, что большинство применений mutable являются признаком недостатка дизайна. В этом случае я подозреваю, что имея iter быть членом class LRU во-первых, это потенциальный недостаток дизайна. Зачем вам это нужно?

Итак, вместо того, чтобы делать iter mutable член, я бы сначала подумал, чтобы он вообще не был членом, а вместо этого использовал бы локальную переменную.

5

В const объекте типа LRU, iter элемент const, поэтому вы не можете изменить его в этом цикле. Вам нужно сделать отдельную копию этого. Вот почему стандартные библиотечные алгоритмы принимают объекты итератора: поэтому они могут изменять объекты итератора для перемещения по последовательности, даже если есть базовый контейнерный объект, который является постоянным.

1

void LRU::displayQueue() const
{
// std::_Deque_iterator<int, const int&, const int*> l_iter = m_buffer.begin();
for(auto l_iter = m_buffer.begin(); l_iter != m_buffer.end(); ++l_iter)
std::cout << (*l_iter) << " ";
std::cout << std::endl;
}

должно сработать. Как говорили другие люди, значение const нельзя изменить. begin() метод на Deque класс перегружен, чтобы возвращать постоянные или неконстантные значения, и в этом случае он выбирает неконстантные. В качестве альтернативы, вы можете явно обозначить тип iter как не являющийся const.

1

Поскольку ваша функция-член является константой, это означает, что вы обещаете не изменять никаких членов этой функции. Ну, iter является членом, и вы пытаетесь изменить его в функции, поэтому есть ошибка.

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector