为什么编译器允许在引用 const 迭代器的函数中发送对迭代器的引用?
Why compiler allows send a reference to iterator in function which takes a reference to 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 编译器。
If I get a const reference on a container, I should not be able to change it.
没错。但是,您没有在容器上获得 const 引用。尽管有它的名字,const_iterator
从语言的角度来看 而不是 和 const
。名称 const
是为了向程序员表明您将无法通过此迭代器更改容器。迭代器本身仍然是一个有待更改的公平目标。
此外,迭代器是一个const_iterator
只在函数内部。在函数之外,即在 main
中,它是一个常规的 std::list<int>::iterator
,在函数调用前后保持完全可变。
Microsoft STL 的 list::iterator
源自 list::const_iterator
。这就是为什么您可以毫无问题地将对 iterator
的引用传递给期望 const_iterator
的函数。
函数内部的赋值因此是一个切片赋值,但这在这种情况下没有特别的效果,因为iterator
没有虚函数并且没有引入新成员。
因此,由于作业,您已经悄悄地将 const_iterator
转换为 iterator
。
编辑: 我为此创建了一个连接问题:
https://connect.microsoft.com/VisualStudio/feedback/details/2962643
我对 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 编译器。
If I get a const reference on a container, I should not be able to change it.
没错。但是,您没有在容器上获得 const 引用。尽管有它的名字,const_iterator
从语言的角度来看 而不是 和 const
。名称 const
是为了向程序员表明您将无法通过此迭代器更改容器。迭代器本身仍然是一个有待更改的公平目标。
此外,迭代器是一个const_iterator
只在函数内部。在函数之外,即在 main
中,它是一个常规的 std::list<int>::iterator
,在函数调用前后保持完全可变。
Microsoft STL 的 list::iterator
源自 list::const_iterator
。这就是为什么您可以毫无问题地将对 iterator
的引用传递给期望 const_iterator
的函数。
函数内部的赋值因此是一个切片赋值,但这在这种情况下没有特别的效果,因为iterator
没有虚函数并且没有引入新成员。
因此,由于作业,您已经悄悄地将 const_iterator
转换为 iterator
。
编辑: 我为此创建了一个连接问题:
https://connect.microsoft.com/VisualStudio/feedback/details/2962643