end()迭代器上的算术运算
Arithmetic on end() iterator
设A为std::vector<double>
,
这是否定义明确?
if(!A.empty())
std::vector<double>::iterator myBack = A.end() - 1;
end
迭代器是否只适用于等式和不等式检查?或者,只要我留在容器中,我就可以执行一些指针运算?
在我的平台上,此代码有效。我想知道这是不是便携的。
它是完全有效的,因为vector::iterator
是一个随机访问迭代器。您可以对它执行算术运算,而且它不依赖于平台。
std::vector<double>::iterator it = A.end();
while (it != A.begin()){
--it; //this will skip A.end() and loop will break after processing A.front()
//do something with 'it'
}
但A.end()
是指理论上的超越末端元素,因此它不指向元素,因此不应被取消引用。因此,最佳实践是使用反向迭代器,而不是递减结束迭代器。
for(std::vector<double>::reverse_iterator it = A.rbegin(); it != A.rend(); ++it) {
//do something with 'it'
}
这两个循环做同样的事情,第二个是可以理解的,更干净的方法
如果您注意一些特殊情况,几乎是安全的:
A.end()
为您提供了一个迭代器,用于表示std::vector
末尾之外的位置。您应该不要尝试取消引用它。
如果向量有零个元素,那么A.end() - 1
是而不是定义良好的。在所有其他情况下,只要在容器边界内,就可以执行指针运算。请注意,该标准保证std::vector
数据是连续的,并且以与contains类型的C++数组完全相同的方式进行打包。唯一的例外是std::vector<bool>
,由于标准规定的紧密包装专业化,其表现有所不同。(请注意,sizeof(bool)
是,而不是标准保证具有特定值)。
如果我是你,我会使用A.rbegin()
访问最右边的元素并检查返回值,然后继续并坚持迭代器公式。很容易忘记std::vector<bool>
的专业化。
我意识到这个问题有点老了,但我在这里是针对end() - 1
的,我发现现有的答案和评论信息丰富且合理,但由于缺乏引用,无法令人信服,而且我也不确定它们是否针对vector
。因此,我挖掘了尽可能多的具体信息,以说服自己这里的答案是正确的。
这篇文章代表了我为确认答案所做的研究,基本上是我的笔记,但我试图让它尽可能连贯,我认为它可能有用。如果这里有任何问题,我们将非常感谢您的更正。
重述答案
TL;DR这里是肯定的,这里的答案是正确的,不仅适用于vector
,而且适用于更一般的情况:
如果容器的迭代器类型满足双向迭代器(因此提供递减操作),则以下内容对于任何容器类型始终有效,其中e
初始化为container.end()
的返回值:
- 如果
!container.empty()
,则--e
是有效的 - 如果
!container.empty()
,则++(--e) == container.end()
为真
如果迭代器也满足RandomAccessIterator,那么这些更通用的语句是有效的:
- [0,container.size()]中任何整数n的
e - n
和e -= n
- [-container.size()中任意整数n的
e + n
和e += n
,0]
因此,OP中的vector
示例不仅很好,正如其他答案所指出的那样,而且它定义良好,并保证对任何容器类型都很好。
推理
所以现在我觉得少了一点。首先,从容器要求:
表达式 返回类型 语义 条件 复杂性a.end()
(const_)迭代器 迭代器到a的最后一个元素后的一个 常量
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++中带有List类的迭代器Segfault
- 如何在c++迭代器类型中包装std::chrono
- 集合上的输出迭代器:assign和increment迭代器
- Boost Spirit,获取迭代器内部语义动作
- 对于set上的循环-获取next元素迭代器
- 为什么output_editor Concept不需要output_e迭代器标记
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 无效迭代器上的算术
- 顺序容器和迭代器算术
- 迭代器end()函数与指针算术无法使用
- 如何在c++中对stl迭代器进行平均运算
- 迭代器算术
- C++列出迭代器算术
- end()迭代器上的算术运算
- 对字符串副本执行迭代器运算的更简单方法
- 使用concurrent_vector迭代器的算术:假设从迭代器中减去'begin ()'会给出索引是否安全?
- 为什么标准随机访问迭代器不实现size_t算术?
- 为什么随机访问迭代器的算术运算符接受/返回 int 而不是 size_t?