-1

In the code below, whenever a new member is inserted to the std::vector<int>A, due to memory re-allocations, std::vector<reference_wrapper<int>>B points to a wrong address. Is it possible to make the referencing vector to track the re-allocations and store the correct address always?

#include <iostream>
#include <functional>
#include <vector>
using namespace std;

int main()
{
    vector<int> A (0,3);
    vector<reference_wrapper<int>> B;
    B.push_back ( ref(A[0]) );
    B.push_back ( ref(A[1]) );
    B.push_back ( ref(A[2]) );

    A.push_back (0);

    cout << &A[0] << endl;
    cout << &B[0].get() << endl;

    return 0;
}
Shibli
  • 5,879
  • 13
  • 62
  • 126

2 Answers2

1

The only way I see is to reserve enough memory for the vector that it would not be reallocated when a new element is pushed back provided that you do not remove or insert elements in the middle of the vector.

Take into account that this statement

vector<int> A (0,3);

is wrong.

There has to be

vector<int> A (3,0);

or simply

vector<int> A (3);

You could write

#include <iostream>
#include <functional>
#include <vector>
using namespace std;

int main()
{
    vector<int> A( 3 );
    A.reserve( 4 );

    vector<reference_wrapper<int>> B;

    B.push_back ( ref(A[0]) );
    B.push_back ( ref(A[1]) );
    B.push_back ( ref(A[2]) );

    A.push_back (0);

    cout << &A[0] << endl;
    cout << &B[0].get() << endl;

    return 0;
}

The output can look like

0x9cbd018
0x9cbd018
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

You didn't specify the actual usage for this pattern. So here is some possible solutions:

  1. Store index rather than reference/iterator.
  2. Change A to a list or deque which does not invalidate iterators other than the ones actually changed.
  3. Dynamically allocated all the integers (e.g. std::shared_ptr<int>) and let A and B both store the (shared) pointer.
Siyuan Ren
  • 7,573
  • 6
  • 47
  • 61