-2

I want to know the precise meaning that
std::vector<T>::shrink_to_fit(new_capacity) would invalidate reference.

"If a reallocation happens, all iterators, pointers and references related to the container are invalidated. Otherwise, no changes." --

http://www.cplusplus.com/reference/vector/vector/shrink_to_fit/

Test code:

#include <vector>
#include <iostream>
class Test {
public:
    Test(const std::vector<int>& a) : _a(a) {}
    void print() const {
        std::cout << "[";
        for (auto x:_a) std::cout << " " << x;
        std::cout << " ]\n";
    }   
    const std::vector<int>& _a; 
};
int main() {
    std::vector<int> a;
    a.reserve(100);

    for (int i = 0; i < 10; ++i) a.push_back(i);
    Test t(a);
    t.print();
    a.shrink_to_fit();
    t.print(); // will this always work as expected?
}

If new_capacity is less than old_capacity (so the capacity of the vector shrinks), can the reference (the _a attribute of the test class) be invalidated?

Mikel F
  • 3,567
  • 1
  • 21
  • 33
hamster on wheels
  • 2,771
  • 17
  • 50

3 Answers3

4

What the passage you are referring to means is that iterators or references to elements with the vector being resized can become invalidate.

In the case where _a is a reference, as your comment suggests, _a will continue to be a valid reference to the vector, but any iterators or references to elements within _a will be made invalid.

Mikel F
  • 3,567
  • 1
  • 21
  • 33
3

Yes std::vector::shrink_to_fit() would invalidate references if reallocation occurs. But that unrelated to you sample code - references or pointers to data that vector holds would be invalidated, not reference to vector itself:

std::vector<int> v( 10 );
std::vector<int> &vref = v;
int &ref = v[0];
v.resize(2);
v.shrink_to_fit();
// now ref could be invalid, but vref is perfectly fine
Slava
  • 43,454
  • 1
  • 47
  • 90
3

If new_capacity is less than old_capacity (so the capacity of the vector shrinks), can the reference (the _a attribute of the test class) be invalidated?

no, Test::_a will not be invalidated after:

a.shrink_to_fit();

if you would have a std::vector<int>::iterator _aitr;, which would point to some element of a, then such iterator would be invalidated.

marcinj
  • 48,511
  • 9
  • 79
  • 100
  • I would expect this is the case, because I think the vector is an object with a pointer to the actual memory that holds the data. shrink to fit might change this pointer, but a reference to the vector should still be fine. – hamster on wheels Jan 26 '17 at 21:17
  • @rxu exactly, that is true – marcinj Jan 26 '17 at 21:19