为什么编译器允许在函数中发送对iterator的引用,该函数引用const迭代器?

时间:2016-07-22 11:10:22

标签: c++ visual-studio-2015 const-iterator

我对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}。为什么?如果我在容器上获得const引用,我不能更改它。这是Visual Studio 2015编译器。

2 个答案:

答案 0 :(得分:2)

  

如果我在容器上获得const引用,我应该无法更改它。

那是对的。但是,您没有获得容器上的const引用。尽管名称如此,但从语言的角度来看,const_iterator 并非一个const。名称const用于向程序员表明您无法通过此迭代器更改容器。迭代器本身仍然是一个可以改变的公平目标。

此外,迭代器仅在函数内部为const_iterator。在函数外部,即在main中,它是常规std::list<int>::iterator,在调用函数之前和之后仍然可以完全更改。

答案 1 :(得分:1)

Microsoft STL的list::iterator派生自list::const_iterator。这就是为什么您可以将iterator的引用传递给期望const_iterator而没有问题的函数。

函数内部的赋值因此是一个切片赋值,但在这种情况下没有特别的效果,因为iterator没有虚函数,也没有引入新成员。

因此,由于作业的原因,您已将const_iterator秘密转换为iterator

修改:我为此创建了一个Connect问题:

https://connect.microsoft.com/VisualStudio/feedback/details/2962643