【发布时间】:2016-08-17 16:36:13
【问题描述】:
我有一个自定义类的std::vector(为简单起见,在示例中使用int)。我想保留向量成员的引用/指针/链接/其他。但是,向量经常会删除和添加元素。
为了说明我的观点,在下面的示例中,我采用了指向向量第二个元素的引用或指针。我使用引用/指针来增加所选元素的值。然后我擦除第一个元素,并使用 ref/pointer 再次递增。
参考例子:
std::vector<int> intVect = {1,1,1};
int& refI = intVect.at(1);
refI++;
intVect.erase(intVect.begin());
refI++;
智能指针示例:
std::vector<int> intVect2 = {1,1,1};
std::shared_ptr<int> ptrI = std::make_shared<int>(intVect2.at(1)) ;
*ptrI = *ptrI +1;
intVect2.erase(intVect2.begin());
*ptrI = *ptrI +1;
我希望最终引用元素的值为 3,最终向量由 {3,1} 组成。但是,在参考示例中,最终向量为{2,2},而在指针示例中,最终向量为{1,1}。
了解指针本质上是一个内存地址,我可以理解为什么这种方法可能不可行,但如果它以某种方式可行,请告诉我。
那么更重要的问题是,可以使用哪些替代方法或结构来允许对该元素的某种形式的引用/指针/链接/其他(无论是值还是对象) ) 在向包含它的向量(或其他结构)添加成员或从中删除成员后是否可行?
额外积分:
我实际使用的对象具有position 属性。我有第二个结构需要跟踪对象,以便快速查找哪些对象在哪些位置。我目前正在使用网格(向量向量)来表示可能的位置,每个位置都将索引保存到当前位于该位置的对象的对象向量中。但是,当从向量中删除一个对象时(这种情况非常频繁,每次迭代最多数百次),我目前的手段是循环遍历每个网格位置并减少任何大于删除索引的索引,这既慢又笨拙.非常感谢您在上下文中对这个问题的其他想法,但我的关键问题涉及上述示例。
【问题讨论】:
-
第二个例子不是UB。
shared_ptr完全独立于vector。 -
@underscore_d 我的感觉是
vector不是实现此类事情的最佳方式(非常不稳定的容器)。可能是map?即使使用ints 作为键,使用映射它们将始终保持有效,除非相同的键被擦除 -
@mvidelgauz 确实,或者
list,这似乎更好——只会使erase()d 元素的迭代器无效。 -
@mvidelgauz 如果可以更改容器类型,
std::list将是提供所需行为的最简单的方法。 -
@aschepler 是的,容器类型肯定可以改变,事实上,这是我的问题的症结所在,询问哪些替代方法(因为我的方法在当前状态下显然无效)会达到理想效果。
标签: c++ pointers vector data-structures reference