6

以下代码按预期工作(测试通过),但我想知道以这种方式使用迭代器在 c++ 中是否被认为是一种不好的做法,或者是否可以。

也许这是特定于std::vector其他集合的行为不同并且集合(甚至它们的实现)之间的最佳实践不同?

这在其他语言中肯定是不行的,而且大多数时候更改集合会使迭代器无效并抛出异常。

BOOST_AUTO_TEST_CASE (ReverseIteratorExample) {
    std::vector<int> myvector;
    for(int i = 0; i < 5; i++)
    {
        myvector.push_back(i);
    }

    // is this generally a bad idea to change the vector while iterating?
    // is it okay in this specific case?
    myvector.reserve(myvector.size() + myvector.size() - 2 );
    myvector.insert(myvector.end(), myvector.rbegin() + 1, myvector.rend() -1);

    int resultset [8] = { 0,1,2,3,4,3,2,1 };
    std::vector<int> resultVector( resultset, resultset + sizeof(resultset)/sizeof(resultset[0]) );
    BOOST_CHECK_EQUAL_COLLECTIONS(myvector.begin(), myvector.end(), resultVector.begin(), resultVector.end());
}

总结问题:

  1. 在迭代时更改向量通常是一个坏主意吗?
  2. 在这种特定情况下可以吗?
  3. 这是特定于std::vector和其他集合的行为不同吗?
  4. 集合(甚至它们的实现)之间的最佳实践是否有所不同?
4

1 回答 1

12

这不是有效的代码。标准对序列容器操作的定义(23.2.3@4):

a.insert(p,i,j) - [...] pre:i 和 j 不是 a 的迭代器。

因此,您的代码会调用未定义的行为,因为它违反了操作的先决条件insert

如果不是 using ,而是编写了一个从to迭代并调用所有值insert的循环,那么您的代码将是有效的:这是因为只有在需要重新分配时才会使向量迭代器无效,并且您的调用 to确保不是这种情况。myvector.rbegin() + 1myvector.rend() -1push_backpush_backreserve

一般来说,虽然在某些情况下在迭代容器时修改容器是可以的(例如上面描述的循环),但您必须确保在这样做时迭代器不会失效。发生这种情况时特定于每个容器。

于 2013-04-23T16:18:06.340 回答