C++ 递减迭代器

C++ 递减迭代器,c++,C++,我在双向数据结构(实际上是向量)中有一个普通迭代器。现在,我想从当前位置对过去的x元素执行一个操作。尽管最后一个x可能是向量的第一个元素,但之前至少会有x个元素 我已经写了这个代码 vector<Record>::iterator it = itCurrentRecord; for (unsigned int i = 0; i < length; i++) { (it--)->length = length; } vector::迭代器it=itCurrentR

我在双向数据结构(实际上是向量)中有一个普通迭代器。现在,我想从当前位置对过去的x元素执行一个操作。尽管最后一个x可能是向量的第一个元素,但之前至少会有x个元素

我已经写了这个代码

vector<Record>::iterator it = itCurrentRecord;
for (unsigned int i = 0; i < length; i++)
{
    (it--)->length = length;
}
vector::迭代器it=itCurrentRecord;
for(无符号整数i=0;ilength=长度;
}
这安全吗?我担心当它指向第一个元素时,最后的减量将导致迭代器指向第一个元素之前的一个元素,这是无效的

如果是这样的话,我如何以安全的方式重写它


谢谢使用反向迭代器:

vector<Record>::reverse_iterator it = itCurrentRecord;
for (unsigned int i = 0; i < length; i++)
{
    (it++)->length = length;
}
vector::reverse\u迭代器it=itCurrentRecord;
for(无符号整数i=0;ilength=长度;
}

它允许在开始之前语义上指向一,就像普通迭代器允许指向一个过去的结束一样。

您的关注是有效的。由于这是一个随机访问迭代器,因此可以使用算术避免未定义的行为:

vector<Record>::iterator it = itCurrentRecord;
for (unsigned int i = 0; i < length; i++)
{
    (it - i)->length = length;
}
vector::迭代器it=itCurrentRecord;
for(无符号整数i=0;i长度=长度;
}

您可以在范围的开始处启动
并向前迭代

vector<Record>::iterator it = std::prev(itCurrentRecord, length - 1);
for (unsigned int i = 0; i < length; i++)
{
    (it++)->length = length;
}
vector::iterator it=std::prev(itCurrentRecord,长度-1);
for(无符号整数i=0;ilength=长度;
}

注意:
std::prev
是C++11的一项功能。

除了前面提到的解决方案之外,您还可以执行以下操作:

// assume vector<Record> v is filled;
vector<Record>::iterator it = currentRecord;
for_each(v.begin(), it, [&](Record& r)
{
    r.length = length;
});
//假设向量v已填充;
向量::迭代器it=currentRecord;
对于_each(v.begin(),it,[&](Record&r)
{
r、 长度=长度;
});
或者,如果您需要/想要倒退(例如,如果迭代顺序很重要):

for_each(反向迭代器(it)、v.rend()、[&](记录与r)
{
r、 长度=长度;
});

您担心在开始之前指向一个是有效的(无效迭代器)。@MarkB:是,迭代器无效。但它是UB。如果只是未指定,那么只要迭代器不再使用就可以了。这是错误的:“允许在开始之前指向一个,就像允许普通迭代器指向一个过去的端点一样”@DieterLücking为什么?这不正是
end()
rend()
返回的内容吗?@ZacHowland:这不是一个可以用来赢得争论的参考,因为它是非规范性的(只用于快速检查)。如果你要引用参考文献,请引用标准。@DieterLücking挑剔,明白了。但这是反向迭代器存储的内容,而不是它在语义上表示的内容。好的,我明白你的意思,但这并不意味着OPs最初的关注点是无效的,也不意味着我建议的解决方案存在问题。@LokiAstari:24.5.1:“反向迭代器与其对应的迭代器I之间的基本关系是由标识建立的:&*(反向迭代器(I))==&*(I-1)。”换句话说,如果i==0,
rend()
等于范围/数组中第一项之前的1项。在这个特定示例中,顺序并不重要,但如果您假设顺序重要,则会产生一个更有趣的问题。
for_each(reverse_iterator<vector<Record>::iterator>(it), v.rend(), [&](Record& r)
{
    r.length = length;
});