C++ 向量中的无效迭代器

C++ 向量中的无效迭代器,c++,vector,iterator,language-lawyer,undefined-behavior,C++,Vector,Iterator,Language Lawyer,Undefined Behavior,我知道擦除将使迭代器在擦除点和之后失效。考虑: std::vector<int> vec = {1, 2, 3, 4, 5}; std::vector<int>::iterator it = vec.end() - 1; //last element vec.erase(vec.begin()); //shift everything one to the left, 'it' should be the new 'end()' ? std::cout <<

我知道擦除将使迭代器在擦除点和之后失效。考虑:

std::vector<int> vec = {1, 2, 3, 4, 5};
std::vector<int>::iterator it = vec.end() - 1; //last element
vec.erase(vec.begin()); //shift everything one to the left, 'it' should be the new 'end()' ?
std::cout << (it == vec.end()); //not dereferencing 'it', just comparing, UB ?
std::vector vec={1,2,3,4,5};
std::vector::iterator it=vec.end()-1//最后元素
向量擦除(vec.begin())//将所有内容向左移动一次,“它”应该是新的“end()”?

std::cout任何指向被删除元素上或之后的元素的迭代器都将失效。所以

  • 是的,这是UB(尽管它是引擎盖下的指针。)

  • 尽管有明显的似是而非的道理,但我还是再次重申了这一点


  • 一旦您的迭代器失效,甚至可能无法将其与其他内容进行比较:

    [C++14:24.2.1/10]:
    无效迭代器是可能是单数的迭代器

    [C++14:24.2.1/5]:
    […]大多数表达式的结果对于奇异值是未定义的;唯一的例外是销毁保存奇异值的迭代器,将非奇异值赋值给保存奇异值的迭代器,对于满足
    DefaultConstructible
    要求的迭代器,使用值初始化迭代器作为复制或移动操作的源。[……]

    请注意,这意味着您也无法将默认构造的迭代器与任何
    .end()
    进行比较


    与流行的“指针只是内存地址”的观点相反,这些规则在很大程度上也适用于指针。实际上,迭代器规则是指针规则的概括。

    谢谢你的回答,我同意你所说的一切。然而,在这种特殊情况下,
    它可能是非单数的。看见虽然
    无效,但它与容器“关联”(更准确地说,是关联的),这使得它不是单数的。@PoweredByRice:我在该页上没有看到任何相关和/或权威性的声明。你自己说的:是关联的,过去式是关键。它不再关联。所以我想问题是:无效迭代器何时是非单数的?@PoweredByRice:我不确定。我目前的解释是,这归结为迭代器失效和实际“物理”破坏迭代器之间的区别。也就是说,例如,迭代器在发生重新灰化后无效,即使容器的结果状态可能与之前相同。我认为标准要求我们考虑所有可能的奇异迭代器,并在此基础上继续进行。一些C++库使用向量迭代器的类类型(这导致了由于ADL而导致的跨库中相同代码的不同行为,例如:<代码>查找(V.Sub(),V.Enter(),X);)。例如,在调试模式下,他们试图诊断迭代器到不同向量的比较