Почему компилятор позволяет отправлять ссылку на итератор в функции, которая принимает ссылку на константный итератор?

Я немного запутался с 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, который остается полностью изменяемым до и после вызова функции.

Другие вопросы по тегам