【问题标题】:Vector Iterator not decrementable?向量迭代器不可递减?
【发布时间】:2015-03-24 05:13:03
【问题描述】:

有人能解释一下为什么这个代码片段会通过循环运行一次,然后给出断言失败表达式:向量迭代器不可递减吗?

for (auto an = a.rbegin(); an != a.rend(); ++an, indexA--) //first number 
{
        for (auto bn = b.rbegin(); bn != b.rend(); ++bn) //second number
        {
            if (*an - *bn >= 0)
            {
                returnVal.push_back(*an - *bn);
                a.pop_back();
                b.pop_back();
            }
            else
            {
                brrow = *an + 10;
                a.at(indexA - 1) = a.at(indexA - 1) - 1; // remove 1 from the spot ahead of current digit
                returnVal.push_back(brrow - *bn);
                a.pop_back();
                b.pop_back();
            }
        }   
}

【问题讨论】:

  • 你在迭代过程中修改vector的内容!这使得迭代器无效!
  • 有没有办法可以在我 pop_back 时重新验证迭代器?
  • 不!这是不可能的 AFAIK。
  • 呃...实际上 pop_back() 只会使结束和返回无效。其他迭代器应该仍然有效。
  • 使end() 无效使rbegin() 无效。

标签: c++ vector


【解决方案1】:

根据您的 cmets,您似乎想同时移动两个迭代器范围 - 只需要一个 for 循环,如下所示:

auto an = a.rbegin();
for (auto bn = b.rbegin();
     an != a.rend() && bn != b.rend();
     ++an, ++bn, indexA--)
    if (*an - *bn >= 0)
        returnVal.push_back(*an - *bn);
    else
    {
        brrow = *an + 10;
        --(a.at(indexA - 1)); // remove 1 from the spot ahead of current digit
                              // shouldn't you check for rend() first????
        returnVal.push_back(brrow - *bn);
    }

请注意,两个迭代器都可以声明为for-loop local 如果你知道它们将是完全相同的类型:

for (auto an = a.rbegin(), bn = b.rbegin(); ...

【讨论】:

  • 谢谢,我一直在努力寻找一个 O(n) 的解决方案。出于某种原因,我的思绪停留在“我有 2 个向量,我需要 2 个循环”这确实消除了我所遇到的错误。
【解决方案2】:

pop_back() 将使您的迭代器无效。

下面有更详细的解释(Does pop_back() really invalidate *all* iterators on an std::vector?):

这是你的答案,直接来自《神圣标准》:

23.2.4.2 向量满足容器和可逆容器(在 23.1 中的两个表中给出)和 序列,包括大多数可选的序列要求 (23.1.1)。

23.1.1.12表68表达式a.pop_back()返回typevoid操作语义a.erase(--a.end())容器向量, 列表, 双端队列

请注意 a.pop_back 等价于 a.erase(--a.end())。看向量的 擦除细节:

23.2.4.3.3 - 迭代器擦除(迭代器位置) - 效果 - 使擦除点之后的所有迭代器和引用无效

因此,一旦调用 pop_back,任何迭代器都会 final 元素(现在不再存在)无效。


更多信息:FAQ“迭代器失效规则”: Iterator invalidation rules

【讨论】:

  • 这如何回答 OP 的问题?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-25
  • 2021-11-21
  • 1970-01-01
  • 2011-05-29
  • 1970-01-01
  • 1970-01-01
  • 2012-08-16
相关资源
最近更新 更多