const_iterator与迭代器的比较是否定义明确?

时间:2016-02-14 10:43:57

标签: c++ iterator comparison-operators const-iterator

请考虑以下代码:

vec.end()

我在这里介绍了一个拼写错误:在比较中,我调用了vec.cend()而不是iterator。这似乎与gcc 5.2一样有效。但根据标准,它实际上是否定义明确?可以安全地比较const_iterator'// Sheet1 object has a tab name of "My Sheet 1" Dim i As Integer i = 1 Sheet1.Range("A1").Value = "Foo" '// This will work. Sheet(i).Range("A1").Value = "Foo" '// This will not work. 吗?

3 个答案:

答案 0 :(得分:31)

令人惊讶的是,C ++ 98和C ++ 11没有说您可以将iteratorconst_iterator进行比较。这会导致LWG issue 179LWG issue 2263。现在在C ++ 14中,§23.2.1[container.requirements.general] p7

明确允许这一点。
  

在表达式中

i == j
i != j
i < j
i <= j
i >= j
i > j
i - j
     

其中ij表示容器的iterator类型的对象,或者   两者都可以被容器的const_iterator对象替换   类型引用相同的元素,语义没有变化。

答案 1 :(得分:9)

见§23.2.1,表96:

X::iterator

[...]

  

符合前向迭代器要求的任何迭代器类别。

     

可转换为X::const_iterator

所以,是的,它定义明确。

答案 2 :(得分:8)

C ++ 11标准中的表96,在第23.2.1节中,为任何容器类型a.cend()(包括{{1}定义X操作语义 }})如下:

std::vector

所以答案是肯定的,因为根据这个定义,const_cast<X const &>(a).end() 引用容器中与cend()相同的元素/位置,而end()必须可转换为X::iterator(同样也在同一表(*)中指定的要求。

(对于X::const_iteratorbegin()的答案也是肯定的,原因相同,如同一张表中所定义。)

(*)在评论中已经指出其他答案可转换性并不一定意味着比较操作cbegin()将始终有效,例如如果i1==i2是迭代器类型的成员函数,则只接受右侧参数的隐式转换,而不接受左侧参数。 24.2.5 / 6个州(关于前向迭代器operator==()a):

  

如果ba都可以取消引用,那么b当且仅当a == b*a绑定到同一个对象时

尽管迭代器*bend()不能解除引用,但上述语句意味着必须以这样的方式定义cend(),即使operator==()也可以进行比较是一个常量迭代器而a不是,反之亦然,因为24.2.5一般是关于前向迭代器,包括const和非const版本 - 这很明显,例如从24.2.5 / 1。这就是为什么我确信表96中提到可兑换性的措辞也意味着可比性。但是正如cpplearner @后来的回答所描述的那样,只有在C ++ 14中才能明确说明这一点。