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

时间:2014-06-30 17:45:06

标签: c++ stdvector

当使用原始数据类型过滤向量时,我通常会这样做:

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将元素过滤成第三个矢量。另一个想法是使用循环这样做。完成此任务的最佳方法是什么?我应该使用引用而不是指针吗?

3 个答案:

答案 0 :(得分:1)

原始指针适用于非拥有语义,但您必须能够保证它们保持有效&lt; =&gt;该矢量不会被重新分配。

向量中的索引更加健壮,如果对象更改位置/被移除,它们只会过时。

无论如何,如果复制对象的价格昂贵,移动它们也很昂贵吗?考虑std::unique_ptr然后堆分配它们(std::shared_ptr可能仍然太重,即使你使用std::make_shared)。

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

答案 1 :(得分:0)

您可以尝试这样的事情:

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));

但是你需要知道这些指针是新鲜的,除非你向向量追加任何元素,std :: vector可以在需要时重新分配内存区域然后在匹配容器中重新分配所有指针将失效。

答案 2 :(得分:0)

迭代向量...将计数变量初始化为零。

当元素符合条件时

1)将它与索引计数的元素交换。

2)增加计数。

最后擦除向量中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());