使用对 std::vector 的某些元素的引用,或这些元素在向量中的位置来迭代它们

Posted

技术标签:

【中文标题】使用对 std::vector 的某些元素的引用,或这些元素在向量中的位置来迭代它们【英文标题】:Use references to some elements of a std::vector, or the position of such elements in the vector, to iterate over them 【发布时间】:2013-07-08 01:28:30 【问题描述】:

在我正在编写的应用程序中,我将数据存储在对象中,例如

std::vector<my_struct> db;

而且我经常需要引用它们的一些元素并使用一个 std::set 我将它们的位置存储在向量中(不会改变)

std::set<int> elements_i_like; 

然后,我使用

访问 db 元素
for ( auto it = elements_i_like.begin(); it!=elements_i_like.end(); it++)
    db[*it].do_something();

我有一个疑问,在性能方面,不将元素的索引存储在向量中,而是直接引用它们会更好吗?

std::vector<my_struct> db; //where i store the data (edit form original question)
std::set<my_struct&> elements_i_like;//reference to the specific structs, stored in the vector, that i want to iterate on

然后做

for( auto it= elements_i_like.begin(); it!=elements_i_like.end(); it++)
    (*it).do_something();

这样做会有什么缺点吗? 谢谢。

【问题讨论】:

一个缺点是您不能将引用存储在容器中... 但是你可以存储std::reference_wrappers. 在我看来,就 C++11 之前代码的性能而言,向量非常“饥饿”,请记住,向量是被授予在内存中连续的数据块(就像普通的旧数组),有时当您向向量添加一个元素时,整个向量需要重新定位,并且向量增长得越多,您在内存操作方面付出高昂成本的机会就越高。一切都取决于您对“性能”的含义。 @user2485710:从 OP 的问题来看,听起来向量/集合组合是给定的。 (还要注意向量插入是 O(1) 摊销的。) 您是否在将索引/引用存储在集合中之后添加更多元素?如果添加更多元素,引用可能会失效(而索引不会)。 【参考方案1】:

您不能将引用存储在容器中,并且在任何情况下,即使编译器/语言允许,您仍然需要两次取消引用来评估每次迭代。

顺便说一句,如果 C++11 可用,您可以将循环重写为:

for(auto& elem : elements_i_like)
    elem.do_something();

【讨论】:

谢谢。这似乎是一个很好的解决方案。我只是想知道:我应该如何声明 elements_i_like? 好的,我想出了如何在循环范围内使用它。最后,我认为 int 将是我最初问题的最佳选择,主要是因为 jogojapan 所说的。

以上是关于使用对 std::vector 的某些元素的引用,或这些元素在向量中的位置来迭代它们的主要内容,如果未能解决你的问题,请参考以下文章

如何安全地引用 std::vector 元素?

构造过程中对向量中元素的引用

指向 std::vector 和 std::list 元素的指针

通过使用 pybind11 的虚函数通过引用传递 std::vector 的问题

对“std::vector<int, std::allocator<int>>”类型空指针的引用绑定

如何创建 C++ 用户定义的类,以便该类的 std::vector 不包含该类的某些成员