Почему компилятор позволяет отправлять ссылку на итератор в функции, которая принимает ссылку на константный итератор?
Я немного запутался с const_iterators. Например, давайте рассмотрим функцию:
void functionForConstIterator(std::list<int> const& list, std::list<int>::const_iterator& const_iter)
{
const_iter = list.begin();
}
Теперь я могу написать:
void main()
{
std::list<int> myList = {1, 2, 3, 4, 5};
std::list<int> const& listRef = myList;
std::list<int>::iterator iter;
functionForConstIterator(listRef, iter);
*iter = 7;
for (auto it = myList.begin(); it != myList.end(); ++it)
std::cout << *it << " ";
}
Выход составляет {7, 2, 3, 4, 5}. Зачем? Если я получаю постоянную ссылку на контейнер, мне не нужно ее менять. Это компилятор Visual Studio 2015.
2 ответа
Microsoft STL's list::iterator
происходит от list::const_iterator
, Вот почему вы можете передать ссылку на ваш iterator
к функции, ожидающей const_iterator
без проблем.
Таким образом, присваивание внутри функции является присваиванием срезами, но в этом случае это не имеет особого эффекта, поскольку iterator
не имеет виртуальных функций и не вводит новых членов.
Таким образом, вы незаметно превратили const_iterator
для iterator
благодаря назначению.
Изменить: я создал проблему подключения для этого:
https://connect.microsoft.com/VisualStudio/feedback/details/2962643
Если я получу постоянную ссылку на контейнер, я не смогу ее изменить.
Вот так. Однако вы не получаете постоянную ссылку на контейнер. несмотря на свое имя, const_iterator
это не const
с точки зрения языка. Имя const
означает указать программистам, что вы не сможете изменить контейнер через этот итератор. Сам итератор остается хорошей целью для изменения.
Более того, итератор является const_iterator
только внутри функции. Вне функции, то есть в main
, это обычный std::list<int>::iterator
, который остается полностью изменяемым до и после вызова функции.