代码之家  ›  专栏  ›  技术社区  ›  Akusete

STL容器中的持久引用

  •  6
  • Akusete  · 技术社区  · 15 年前

    当使用C++ STL容器时,在什么条件下必须访问参考值? 例如,在对容器进行下一个函数调用之后,是否有任何引用失效?

    {
    std::vector<int> vector;
    vector.push_back (1);
    vector.push_back (2);
    vector.push_back (3);
    
    vector[0] = 10;       //modifies 0'th element
    
    int& ref = vector[0];
    ref = 10;             //modifies 0'th element
    
    vector.push_back (4);
    ref = 20;             //modifies 0'th element???
    
    vector.clear ();
    ref = 30;             //clearly obsurd
    }
    

    我理解在大多数STL实现中,这是可行的,但我对标准声明所要求的内容感兴趣。

    ——编辑: 我很感兴趣,因为我想试试STXXL( http://stxxl.sourceforge.net/ 库为C++,但我意识到容器返回的引用在多个读取中不持久,因此不兼容,而不需要对我现有的STL代码进行更改(无论多么肤浅)。一个例子:

    {
    std::vector<int> vector;
    vector.push_back (1);
    vector.push_back (2);
    
    
    int& refA = vector[0];
    int& refB = vector[1]; //refA is not gaurenteed to be valid anymore
    }
    

    我只是想知道这是否意味着STXXL容器不100%兼容,或者实际上,如果我一直以不安全/依赖于实现的方式使用STL容器。

    4 回复  |  直到 15 年前
        1
  •  12
  •   j_random_hacker    15 年前

    关于插入向量,标准在23.2.4.3/1中说:

    [ insert() ]导致重新分配,如果 新尺寸大于旧尺寸 容量。如果没有重新分配, 所有迭代器和引用 插入点保留前 有效。

    (尽管这实际上是在谈论 插入() ,表68表明 a.push_back(x) 必须等于 a.insert(a.end(), x) 对于任意向量 a 价值 x 这意味着如果你 reserve() 预先有足够的内存,然后(只有这样)迭代器和引用保证不会在您 插入() push_back() 更多项目。

    关于移除物品,23.2.4.3/3表示:

    [ erase() ]使所有 后面的迭代器和引用 擦除点。

    分别根据表68和表67, pop_back() clear() 相当于对 擦除() .

        2
  •  8
  •   aJ.    15 年前

    向量的一些基本规则:

    • 重新分配将全部失效 引用、指针和迭代器 对于向量的元素。
    • 插入 可以 使引用无效, 指针和迭代器。
    • 插入或移除元件 使引用、指针和 引用以下内容的迭代器 元素。
    • 如果插入导致重新分配, 它使所有引用无效, 迭代器和指针。
        3
  •  1
  •   ChrisW    15 年前

    我希望引用只能通过任何显式或隐式的方式无效。 resize() (也见 max_size ,请 capacity reserve 方法)。

        4
  •  1
  •   Naveen    15 年前

    矢量将在重新分配时使其迭代器和引用失效,这取决于它当前的容量。尽管上述代码在某些情况下可能有效,但您不应该依赖于此,因为在push-back(4)调用后,引用可能会失效。