调整大小后保持对向量元素的引用有效

时间:2018-06-15 00:32:13

标签: c++ vector reference

如果我们引用一个vector元素然后调整向量大小,那么引用就不再有效了,迭代器也是如此:

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]的对象即使物体被移动了吗?

我已经尝试过写一个小助手班来帮助解决这个问题,但是我不确定这是最好的方法,还是会失败?

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&amp;或者通过“解引用”来解决问题。操作者:

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;

其中已打印出例外情况:

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

除了有一个帮助类之外,还有更好的方法可以做到这一点吗?在某些情况下辅助类是否不可靠?

我还在reddit中遇到this个帖子,但似乎他们没有讨论那里的助手类

2 个答案:

答案 0 :(得分:2)

你可以做的一件事就是有一个指针向量,而不是一个实例向量。那当然有它自己的问题,但如果你必须有对象引用存活矢量调整大小,它将做到这一点。

答案 1 :(得分:1)

向量的任何重新分配都将使任何指针,引用和迭代器无效。

在您的示例中,您的HelperClass在以下方面毫无用处:

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

与:

相同
cout <<  ref << " " << *itr << " " << vec[0] << " " << vec[0] << endl;

如果发生重新分配,只需使用迭代器接口.begin() .end()再次访问迭代器。