如何保持引用/指针/链接到vector元素后更改为vector
How to maintain reference/pointer/link to vector element after change to vector?
我有一个自定义类的std::vector
(为了简单起见,在示例中使用int
)。我想保留一个指向向量成员的引用/指针/链接/其他。然而,vector经常删除和添加元素。
为了说明我的观点,在下面的示例中,我接受指向vector的第二个元素的引用或指针。我使用引用/指针来增加所选元素的值。然后擦除第一个元素,并使用ref/指针再次自增。
参考例子: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}
。
理解指针本质上是一个内存地址,我可以理解为什么这个方法可能不可能,但如果它不知何故是,让我知道。
更重要的问题是,可以使用什么替代方法或结构来允许某种形式的ref/指针/链接/其他指向包含它的向量(或其他结构)的元素(无论是值还是对象),在向其添加成员或从其删除成员后是可行的?
额外学分:
我实际工作的对象有一个position
属性。我有第二个结构,它需要跟踪对象,以便快速查找哪个对象在哪个位置。我目前使用网格(向量的向量)来表示可能的位置,每个位置都包含对象向量的索引,用于当前位置的对象。但是,当从向量中删除对象时(这种情况非常频繁,每次迭代多达数百次),我目前的方法是遍历每个网格位置并递减大于已删除索引的索引,这种方法既慢又笨拙。在上下文中对这个问题的其他想法非常感谢,但我的关键问题与上述示例有关。
一个可能的选择是让vector存储std::shared_ptr
对象,并发出std::weak_ptr
或std::shared_ptr
对象来引用所讨论的对象。
std::vector<std::shared_ptr<int>> ints;
for(size_t i = 0; i < 10000; i++) {
ints.emplace_back(std::make_shared<int>(int(i)));
}
std::weak_ptr<int> my_important_int = ints[6000];
{
auto lock = my_important_int.lock();
if(lock) std::cout << *lock << std::endl;
else std::cout << "index 6000 expired." << std::endl;
}
auto erase_it = std:remove_if(ints.begin(), ints.end(), [](auto & i) {return (*i) > 5000 && ((*i) % 4) != 0;});
ints.erase(erase_it, ints.end());
{
auto lock = my_important_int.lock();
if(lock) std::cout << *lock << std::endl;
else std::cout << "index 6000 expired." << std::endl;
}
ints.erase(ints.begin(), ints.end());
{
auto lock = my_important_int.lock();
if(lock) std::cout << *lock << std::endl;
else std::cout << "index 6000 expired." << std::endl;
}
应该打印出:
6000
6000
index 6000 expired.
存储键/值对的容器可能适合您。例如:std::map
、std::unordered_map
。
当使用这些容器时,您将通过存储键来保持对所需对象的引用。如果要修改该对象,只需使用该键在容器中查找即可。现在,您可以随心所欲地添加/删除其他对象,而不会影响正在讨论的对象(假设添加/删除的对象具有唯一键)。
如果有一种方法可以让您继续使用矢量并改变管理对象的方式,那么您将不会获得比现在更好的性能。
否则,您可以使用稳定向量(这里是boost版本)。它本质上是一个指针向量,这赋予了它迭代器和引用的稳定性。这意味着迭代器(指针)和对元素的引用不会因除删除元素本身以外的任何操作而失效。当然,这有一些很大的缺点,主要是在性能上。两个主要的性能问题是每次想要访问元素时都要遍历一个指针,以及元素不是连续存储的(这当然会影响迭代的速度)。
然而,与其他指针较多的数据类型(列表、集合、映射)相比,它也有优势。主要是,它在常量时间内执行查找和回推,尽管它比普通向量慢。然后,如果你真的需要性能,你可能想要保留你的矢量,并重新考虑你的设计。
- 对 Vector 元素 (C++) 的push_back操作
- 有没有函数可以直接获取 std::vector 元素的大小?
- 使用 stl 排列 std::vector 元素的最短解决方案
- 在不调用构造函数的情况下创建 Vector 元素
- 分配std :: vector元素的两种方法
- 如何对std::vector元素中的对象使用shared_mutex
- 在 GDB 漂亮的打印机中显示特定的 std::vector 元素
- 将分配到std :: vector元素线程安全
- 是否可以使用 std::vector 元素的地址作为指针
- 访问std::vector元素的速度会随着向量大小而减慢
- 指向 std::vector 元素时编译器错误<bool>?
- 通过 std::vector.data() 指向 std::vector 元素的指针指向损坏的数据
- 指向所有 std::vector 元素的指针
- 调用在函数调用期间重新分配的“std::vector”元素的函数是否会导致麻烦
- 使用下标运算符进行Integer Vector元素比较失败,但使用at函数成功
- 填充一个无序的vector元素指针队列
- 将vector元素赋值给调用emplace_back的函数的result
- 调用带有引用vector元素参数的c++函数
- 将vector元素转换为字符串进行比较
- vector元素被覆盖