从矢量中提取子矢量而不复制

时间:2015-05-26 21:17:08

标签: c++ iterator shared-ptr smart-pointers

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

类似的东西:

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) 
{
   .... 
}

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

或者,我可以使用智能指针来执行此操作吗?

3 个答案:

答案 0 :(得分:4)

您无法从另一个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>>(如果您需要修改原始表示,则存储偏移而不是迭代器)。

答案 1 :(得分:4)

每当我说我已经宣誓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

答案 2 :(得分:0)

如果你想要矢量是可变的,不。如果你只想传递一个子向量而不是更改内容,为什么不改变你的各种函数来获取一个开始和结束迭代器而不是传递一个向量?