我有两个迭代器放入容器,一个const和一个非const。比较它们是否存在问题,看它们是否都引用了容器中的同一个对象?这是一个通用的C ++ 11迭代器问题:
可以合法地比较const和非const迭代器以查看是否 它们都指向同一个对象,与其类型无关 容器(即它们都是保证引用的迭代器 到同一个容器或该容器的end()中的对象,但是一个是 const而另一个不是)?
例如,请考虑以下代码:
some_c++11_container container;
// Populate container
...
some_c++11_container::iterator iObject1=container.begin();
some_c++11_container::const_iterator ciObject2=container.cbegin();
// Some operations that move iObject1 and ciObject2 around the container
...
if (ciObject2==iObject1) // Is this comparison allowed by the C++11 standard?
...; //Perform some action contingent on the equality of the two iterators
答案 0 :(得分:12)
是的,这会像你期望的那样工作。
标准保证对于任何容器类型,some_container::iterator
都可以隐式转换为some_container::const_iterator
。
23.2.1 [container.requirements.general]中的第一个表,在将X
定义为包含T
类型对象的容器类型后,具有:
表达式:
X::iterator
返回类型:值类型为
的迭代器类型T
注意:满足前向迭代器要求的任何迭代器类别。可转换为
X::const_iterator
。
表达式:
X::const_iterator
返回类型:值类型为
的常量迭代器类型T
注意:满足前向迭代器要求的任何迭代器类别。
(这些不是真正的表达式,而是类型,而不是“返回类型”,但这就是它们被挤进表格中的方式,主要是表达式。)
所以当你有ciObject2==iObject1
时,编译器会注意到最好的operator==
是ciObject2==some_container::const_iterator(iObject1)
。两个operator==
上的const_iterator
会告诉您它们是否引用相同的元素。
(我没有看到任何明确说明此转换的结果与原始iterator
引用的对象相同。我猜这只是理解。)
答案 1 :(得分:2)
来自§24.2.3/ 1
如果
X
满足T
(24.2.2)和{{},则类或指针类型X
满足值类型Iterator
的输入迭代器的要求1}}(表17 )要求......
因此输入迭代器必须是 EqualityComparable 。
所有标准库容器迭代器必须满足前向迭代器要求(§23.2.1 - 表96 )。由于这些要求是输入迭代器要求的超集,因此遵循这些迭代器必须满足 EqualityComparable 概念。
此外,从§23.2.1 - 表96 ,EqualityComparable
必须可转换为
X::iterator
。
将两者一起添加回答您的问题,标准确实需要将X::const_iterator
与Container::const_iterator
进行比较明确定义(只要两者都是指向同一容器的有效迭代器) )。
答案 2 :(得分:1)
我不认为比较它们有可能存在问题。如果你有一个const迭代器,当你检查它是结束时,迭代器end()
返回的不是const。
答案 3 :(得分:1)
IIRC iterator
隐式转换为const_iterator
。结果必须指向相同的位置。
如果是这样,混合比较将进行转换,然后比较现在兼容的const_iterators。