如何过滤向量并返回指向向量元素的指针向量

How to filter a vector and return a vector of pointer to vector elements

本文关键字:向量 元素 指针 返回 过滤 何过滤      更新时间:2023-10-16

当过滤具有基本数据类型的向量时,我通常这样做:

std::vector<int> v1 = {1,2,3,4,5};
std::vector<int> v2;
std::copy_if(v1.begin(), v1.end(), std::back_inserter(v2),
         [](int const& x) { return criterion(x); } );

现在我有一个包含巨大对象的矢量,复制起来非常昂贵。我想要一个指针列表(std::vector),这些指针指向我的原始向量的特定元素,取决于它们是否满足谓词条件。

我的第一个想法是自己创建这种向量,用指向所有元素的指针填充它,并使用copy_if将元素过滤到第三个向量中。另一个想法是使用循环来做这件事。实现这一目标的最佳方式是什么?我应该使用引用而不是指针吗?

对于非拥有的语义来说,原始指针是可以的,但是您必须能够保证它们保持有效<=>向量不会被重新分配。

进入向量的索引更健壮,它们只有在对象改变位置/被移除时才会失效。

无论如何,如果对象的复制成本如此之高,那么它们的移动成本是否也很高?然后考虑std::unique_ptr并对它们进行堆分配(即使使用std::make_shared, std::shared_ptr的权重可能仍然太大)。

如果您只需要一次序列(或者计算谓词很便宜,并且有一个可接受的选定元素与非选定元素的比例),您可以考虑传递一个自定义迭代器,它会动态地进行过滤。(例如:boost::filter_iterator)

您可以尝试这样做:

std::vector<T> vector; // T is a large object
// filling the vector...
std::vector<const T *> matched;
for (const T& ref: vector) if (criterion(ref))
    matched.push_back(static_cast<const T *>(&ref));

但是你需要注意的是,这些指针将是新鲜的,除非你附加任何元素到vector, std::vector可能会在需要时重新分配内存区域,然后你在匹配容器中的所有指针将无效。

遍历vector…保持count变量初始化为0

当满足元素的条件时,

1)与索引值为count的元素交换。

2)增加计数

最后擦除vector中count中的所有元素。

std::vector<int> v1 = {1,2,3,4,5};
int count =0;
for(itr = v1.begin(); itr !=v1.end(); itr++)
{
if(criterion(*itr))
{
  std::iter_swap(v1.begin()+count,itr);
  count++;
}
}
//delete
vec.erase(v1.begin() + count, v1.end());