Этот метод:
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
?
Вы изменяете объект, устанавливая значение переменной-члена const итератора, тем самым лишая законной силы ограничение вашей функции. Используйте локальную переменную.
const_iterator
только означает, что итератор не может изменить последовательность, но вы не изменяете последовательность, вы изменяете переменную-член итератор сам.
Вы не можете изменить ни одного члена класса в 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
член, я бы сначала подумал, чтобы он вообще не был членом, а вместо этого использовал бы локальную переменную.
В const объекте типа LRU
, iter
элемент const, поэтому вы не можете изменить его в этом цикле. Вам нужно сделать отдельную копию этого. Вот почему стандартные библиотечные алгоритмы принимают объекты итератора: поэтому они могут изменять объекты итератора для перемещения по последовательности, даже если есть базовый контейнерный объект, который является постоянным.
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.
Поскольку ваша функция-член является константой, это означает, что вы обещаете не изменять никаких членов этой функции. Ну, iter является членом, и вы пытаетесь изменить его в функции, поэтому есть ошибка.