如果我们引用一个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个帖子,但似乎他们没有讨论那里的助手类
答案 0 :(得分:2)
你可以做的一件事就是有一个指针向量,而不是一个实例向量。那当然有它自己的问题,但如果你必须有对象引用存活矢量调整大小,它将做到这一点。
答案 1 :(得分:1)
向量的任何重新分配都将使任何指针,引用和迭代器无效。
在您的示例中,您的HelperClass
在以下方面毫无用处:
cout << ref << " " << *itr << " " << hlp << " " << *hlp << endl;
与:
相同cout << ref << " " << *itr << " " << vec[0] << " " << vec[0] << endl;
如果发生重新分配,只需使用迭代器接口.begin()
.end()
再次访问迭代器。