请考虑以下代码:
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.
吗?
答案 0 :(得分:31)
令人惊讶的是,C ++ 98和C ++ 11没有说您可以将iterator
与const_iterator
进行比较。这会导致LWG issue 179和LWG 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
其中
i
和j
表示容器的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_iterator
与begin()
的答案也是肯定的,原因相同,如同一张表中所定义。)
(*)在评论中已经指出其他答案可转换性并不一定意味着比较操作cbegin()
将始终有效,例如如果i1==i2
是迭代器类型的成员函数,则只接受右侧参数的隐式转换,而不接受左侧参数。 24.2.5 / 6个州(关于前向迭代器operator==()
和a
):
如果
b
和a
都可以取消引用,那么b
当且仅当a == b
和*a
绑定到同一个对象时
尽管迭代器*b
和end()
不能解除引用,但上述语句意味着必须以这样的方式定义cend()
,即使operator==()
也可以进行比较是一个常量迭代器而a
不是,反之亦然,因为24.2.5一般是关于前向迭代器,包括const和非const版本 - 这很明显,例如从24.2.5 / 1。这就是为什么我确信表96中提到可兑换性的措辞也意味着可比性。但是正如cpplearner @后来的回答所描述的那样,只有在C ++ 14中才能明确说明这一点。