Кажется, у меня проблема с заменой элементов двух векторов. У меня есть два вектора, x
а также y
которые содержат объекты типа myclass
, myclass
имеет только одного публичного члена w
, Я создаю вектор указателей, указывающих на участников w
из x
а затем поменять местами векторы x
а также y
, Я ожидаю, что вектор указателей все еще будет указывать на w
Члены x
но, похоже, это не так.
Вот тривиальный пример для воспроизведения моей проблемы.
#include <iostream>
#include <vector>
using namespace std;
struct myclass
{
double w;
};int main()
{
vector<myclass> x(10);
for(int i=0; i!=10; i++) x[i].w = i;
for(auto el : x) std::cout << el.w << std::endl; /* prints i */
std::cout << std::endl;
vector<double *> px(10);
for(int i=0; i!=10; i++) px[i] = &x[i].w;
for(auto el : px) std::cout << *el << std::endl; /* prints i */
std::cout << std::endl;
vector<myclass> y(10);
for(int i=0; i!=10; i++) y[i].w = 2*i;
for(auto el : y) std::cout << el.w << std::endl; /* prints 2*i */
std::cout << std::endl;
y.swap(x);
for(auto &el : x) std::cout << &el.w << " " << el.w << std::endl; /* prints 2*i as it should */
std::cout << std::endl;
for(auto &el : px) std::cout << el << " " << *el << std::endl; /* should print 2*i, but prints i */
std::cout << std::endl;
}
Заметить, что x
а также y
поменялись элементами, но px
кадры указывают на старые элементы. Я прочитал это, используя swap
не должен делать недействительными указатели / итераторы. Это правильно или я что-то упустил?
Заранее спасибо!
Указатели и итераторы не аннулируются, но они следуют за содержимым контейнера.
Содержание x
меняются местами в y
, но итераторы и указатели на эти значения будут продолжать указывать на них (хотя они сейчас y
).
Подумайте об этом, как это может работать по-другому? Если бы два контейнера неравной длины были поменяны местами, на что указывали бы элементы на конце более длинного контейнера в более коротком контейнере? Как можно было бы реализовать swap()
в O(1)
должны ли элементы каждого контейнера перемещаться в памяти, чтобы указатели оставались действительными?
Других решений пока нет …