从一个矢量中提取一个子矢量,不需要复制

Extract a subvector from a vector without copy

本文关键字:一个 不需要 复制 提取      更新时间:2023-10-16

我有一个大尺寸的向量,我想根据索引提取它的子向量。但是我不想做一个子向量的新拷贝。我可以使用指针迭代器来返回原始向量的指针吗?

类似:

vector<int> orig = { 0,1,2,3,4,5,6,7,8,9 };
vector<int> index = { 3,5,6,8 };
vector<int> dest (vector<int> orig, vector<int> index) 
{
   .... 
}

我想get的是get dest作为{3,5,6,8},它是指向原始的,而不是新的副本。(index是我要从原始向量中提取的索引向量)

或者,我可以使用智能指针做到这一点吗?

您将无法从另一个std::vector<T>的子范围创建std::vector<T>。但是,您可以根据视图将迭代器存储到拥有实际值的std::vector<T>中:

template <typename Iterator>
class array_view {
    Iterator begin_;
    Iterator end_;
public:
    // ...
    array_view(Iterator begin, Iterator end): begin_(begin), end_(end) {}
    Iterator begin() const { return this->begin_; }
    Iterator end() const   { return this->end_; }
    typename std::iterator_traits<Iterator>::reference
    operator[](std::size_t index) { return this->begin_[index]; }
};

如果你想独立于谁拥有实际的数组来处理相同的类型,事情就变得有点有趣了。在这种情况下,您可能希望创建类似上述array_view<T>的东西,但也要为底层表示存储std::shared_ptr<std::vector<T>>(如果需要修改原始表示,则存储偏移量而不是迭代器)。

每次我说我已经放弃了std::valarray,有人就会提出这样的问题,valarray非常直接地支持。例如:

std::valarray<int> orig = { 0,1,2,3,4,5,6,7,8,9 };
std::valarray<size_t> index = { 3,5,6,8 };
orig[index] = -1;

然后如果(例如)我们打印出orig的元素,代码如下:

for (int i=0; i<orig.size(); i++)
    std::cout << orig[i] << "t";

…我们得到以下结果:

0       1       2       -1      4       -1      -1      7       -1      9

如果您希望向量是可变的,则不需要。如果你只是想传递一个子向量,而不改变其内容,为什么不改变你的各种函数来接受一个开始和结束迭代器,而不是传递一个向量呢?

相关文章: