使用迭代器使用自己的元素追加std :: vector

时间:2013-04-23 16:11:18

标签: c++ iterator stdvector

以下代码按预期工作(测试通过)但我想知道以这种方式使用迭代器在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. 收集(甚至实施)之间的最佳做法有所不同吗?

1 个答案:

答案 0 :(得分:12)

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

  

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

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

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

通常,虽然在某些情况下,在迭代它时修改容器很好(例如上面描述的循环),但是在执行此操作时必须确保迭代器不会失效。发生这种情况时,每个容器都是特定的。

相关问题