调整大小后保持对向量元素的引用有效 [英] Keeping a reference to a vector element valid after resizing

查看:28
本文介绍了调整大小后保持对向量元素的引用有效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我们引用一个向量元素然后调整向量的大小,这个引用就不再有效,迭代器也会发生同样的情况:

If we make a reference to a vector element and then resize the vector, the reference is no longer valid, the same happens with an iterator:

std::vector<int> vec{0, 1, 2, 3, 4, 5};
int& ref = vec[0];
auto itr = vec.begin();

cout <<  ref << " " << *itr << endl;

vec[0] = 7;

cout <<  ref << " " << *itr << endl;

vec.resize(100);
vec[0] = 3;

cout <<  ref << " " << *itr << endl;

打印出来:

0 0
7 7
0 0 // We expected a 3 here

而且我知道只保留对向量本身的引用并调用 vec[0] 会更实用,但只是为了质疑,是否可以保留一个始终为 vec[0] 的对象] 即使对象被移动?

And I know that it would be more practical to just keep a reference to the vector itself and call vec[0], but just for the sake of questioning, is it possible to keep an object that will always be vec[0] even if the object is moved?

我已经尝试编写一个小的帮助类来帮助解决这个问题,但我不确定这是否是最好的方法,或者它是否会失败?

I've tried writing a small helper class to help with this, but I'm unsure if this is the best method or if it can even fail?

template<typename T>
struct HelperClass
{
    std::vector<T>& vec;
    size_t element;

    HelperClass(std::vector<T>& vec_, size_t element_) : vec(vec_) , element(element_) {}

    // Either define an implicit conversion from HelperClass to T
    // or a 'dereference' operator that returns vec[0]
    operator T&() { return vec.at(element); }
    T& operator*() { return vec.at(element); }
};

并通过隐式转换为 T& 来使用它.或通过取消引用"运算符:

And use it by either the implicit conversion to T& or by the 'dereference' operator:

std::vector<int> vec{0, 1, 2, 3, 4, 5};
int& ref = vec[0];
auto itr = vec.begin();
HelperClass<int> hlp = HelperClass<int>(vec, 0); // HelperClass

cout <<  ref << " " << *itr << " " << hlp << " " << *hlp << endl;

vec[0] = 7;

cout <<  ref << " " << *itr << " " << hlp << " " << *hlp << endl;

vec.resize(100);
vec[0] = 3;

cout <<  ref << " " << *itr << " " << hlp << " " << *hlp << endl;

已经打印了例外的内容:

Which already prints what was excepted:

0 0 0 0 
7 7 7 7
0 0 3 3

那么除了使用辅助类之外,还有没有更好的方法可以做到这一点?在某些情况下,辅助类是否会不可靠?

So is there a better way to do this aside from having a helper class and can the helper class be unreliable in some cases?

我也在 reddit 中遇到了这个主题,但他们似乎没有讨论那里的帮助类

I've also come across this thread in reddit, but it seems that they do not discuss the helper class there

推荐答案

您可以做的一件事是拥有一个指针向量而不是实例向量.这当然有其自身的问题,但如果您必须让对象引用幸存下来,那么矢量调整大小就可以做到这一点.

The one thing you could do is have a vector of pointers rather than a vector of instances. That of course has its own passel of issues but if you must have object references survive a vector resize that will do it.

这篇关于调整大小后保持对向量元素的引用有效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆