在反向迭代向量

时间:2010-11-17 15:06:15

标签: c++ stl iteration

我需要迭代从结尾到beginnig的向量。 “正确”的方式是

for(std::vector<SomeT>::reverse_iterator rit = v.rbegin(); rit != v.rend(); ++rit)
{
    //do Something
}

当doSomething涉及了解实际索引时,需要使用rit进行一些计算才能获得它,例如index = v.size() - 1 - (rit - v.rbegin)

如果仍然需要索引,那么我坚信最好使用该索引进行迭代

for(int i = v.size() - 1; i >= 0; --i)
{
    //do something with v[i] and i; 
}

这会发出警告,i已签名且v.size()未签名。 改为

for(unsigned i = v.size() - 1; i >= 0; --i)在功能上是错误的,因为这实际上是一个无限循环:)

做我想做的事情的美学方法是什么

  • 无警告
  • 不涉及演员表
  • 不是过于冗长

我希望我不是在寻找不存在的东西:)

9 个答案:

答案 0 :(得分:54)

正如您所指出的那样,i >= 0条件无条件时的问题是条件始终为真。在初始化i然后在每次迭代后再次减去1时,在检查循环条件后减去1:

for (unsigned i = v.size(); i-- > 0; )

我喜欢这种风格有几个原因:

  • 虽然i将在循环结束时回绕到UINT_MAX,但它不会依赖这个行为 - 如果类型是签。依靠无符号的环绕感觉对我来说有点像黑客。
  • 它只调用size()一次。
  • 它不使用>=。每当我在for循环中看到该运算符时,我必须重新读取它以确保没有一个错误。
  • 如果更改条件中的间距,则可以使用"goes to" operator

答案 1 :(得分:15)

除了多个其他答案中所述的索引之外,没有什么能阻止你的reverse_iterator循环。这样,您可以在// do the work部分中根据需要使用迭代器或索引,以获得最低的额外成本。

size_t index = v.size() - 1;
for(std::vector<SomeT>::reverse_iterator rit = v.rbegin(); 
    rit != v.rend(); ++rit, --index)
{
  // do the work
}

虽然我很想知道你需要什么索引。访问v[index]与访问*rit相同。

答案 2 :(得分:5)

美观赏心悦目! ;)

for(unsigned i = v.size() - 1; v.size() > i; --i)

答案 3 :(得分:2)

我更喜欢反向迭代器变体,因为它仍然易于解释并允许避免与索引相关的错误。

有时您只需使用BOOST_REVERSE_FOREACH,这会使您的代码看起来如下:

reverse_foreach (int value, vector) {
   do_something_with_the_value;
}

实际上,你总是可以对这些类型的循环使用foreach语句,但它们会变得有点不明显:

size_t i = 0;

foreach (int value, vector) {
   do_something;
   ++i;
}

答案 4 :(得分:0)

尝试做一会儿:

std::vector<Type> v;
// Some code 
if(v.size() > 0)
{
    unsigned int i = v.size() - 1;
    do
    {
        // Your stuff
    }
    while(i-- > 0);
}

答案 5 :(得分:0)

嗨我认为更好的方法是在第一个示例中使用迭代器,如果需要获取迭代器索引,可以使用 std :: distance来计算它,如果我理解你的问题

答案 6 :(得分:0)

循环条件i != std::numeric_limits<unsigned>::max() ...或者如果你认为它是详细的,请使用UINT_MAX。 或其他方式:
for(unsigned j=0, end=v.size(), i=end-1; j<end; --i, ++j)

for(unsigned end=v.size(), i=end-1; (end-i)<end; --i)

答案 7 :(得分:-2)

for (it = v.end()-1; it != v.begin()-1; --it)
{
}

"goes to" operator绝对是我头脑中的混乱。

答案 8 :(得分:-3)

我认为:

for(unsigned i = v.size() - 1; i >= 0; --i)
如果你检查

就可以了

!v.empty()

更早的版本。