【问题标题】:Control flow with iterators使用迭代器控制流
【发布时间】:2021-12-29 13:48:57
【问题描述】:

假设我有这样的事情:

void myFunk(std::vector<T>& v, std::vector<T>::iterator first, std::vector<T>::iterator last) {
    while (first != last) {
        if ((*first) > (*last)) {
            T someT;
            v.push_back(someT);
        }
        first++;
    }
}

int main(){
    std::vector<T> foo = {some, T, values};
    myFunky(foo, foo.begin(), foo.end())
    return 0;
}

这会导致无限循环,还是会在foo.size() 迭代后结束?换句话说,last 迭代器会随着foo 的增长而更新,还是会保留函数调用中给定的值?

我假设last 会改变,因为它是一个指向位置的指针,但需要一些确认。

【问题讨论】:

    标签: c++ vector iterator controls flow


    【解决方案1】:

    这会导致无限循环,还是会在foo.size() 迭代后结束?

    两者都不是。您正在做的是未定义的行为,原因如下:

    • 您正在修改vector,同时迭代它。

      如果向量在推送新项目时重新分配其内部存储,则所有现有的迭代器进入vector无效,包括您用于循环的两个迭代器。但即使只是推送一个新项目,至少也会使 end() 迭代器无效。

      Iterator invalidation rules for C++ containers

    • 您正在取消引用 end() 迭代器,它从不引用有效元素。

    我假设last 会改变,因为它是指向某个位置的指针

    它不能改变,因为你将它按值传递给myFunc 函数,所以它是原始end() 迭代器的副本。如果end() 改变值,last 不会改变值,因为它是一个副本

    在任何情况下,迭代器都不一定实现为指针,但指针是有效的迭代器。但在这种情况下没关系。即使vector::iterator 只是一个简单的指针,last 在每次推送/重新分配时仍然会失效。

    【讨论】:

    • 按值传递是经过深思熟虑的 - 其想法是 尝试 使向量在当前值中迭代,同时在末尾附加新值。有道理我在运行时遇到内存访问冲突。感谢您提供无效规则插件(我知道我要查找的内容已记录在案,但不知道如何表达)。并感谢您的回答。真的把事情弄清楚了。干杯!
    • 我建议将插入缓存到本地向量,然后在迭代完成后将其附加到目标向量的末尾。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多