2015-04-29 151 views
2

我想提取一个子矢量。然后修改其影响原始矢量的元素。我的示例代码如下:子矢量修改原始矢量

#include <vector> 
#include <iostream> 

using namespace std; 

void printvec(vector<int>& v){ 
     for(int i = 0;i < v.size();i++) {cout << v[i] << " ";} 
     cout << endl; 
} 

int main(){ 
     vector<int> original; 
     for(int i = 1;i <= 10;i++) original.push_back(i); 
     printvec(original); 

     vector<int> subvector(original.begin()+4, original.end()-2); 
     subvector[0]=0; 
     subvector[1]=0; 
     printvec(subvector); 
     printvec(original); 
     return 0; 
} 

在上面的代码中,子向量不会修改向量。可以有人指向我一个优雅的方式,使一个子矢量修改原始矢量(希望没有显式使用指针,如果可能的话)。

+0

int * subvector = original.begin()+ 4;'会做的伎俩,虽然它绝对使用指针。 – dasblinkenlight

+0

@dasblinkenlight:这不会给你一个'size()'函数;) – MikeMB

回答

0

线:

vector<int> subvector(original.begin()+4, original.end()-2); 

创建一个新的载体和复制从original.begin()+4元素到original.end()-2到新的一个。即使有了指针,我也没有办法调用优雅来达到你想要的效果,因为对原始矢量(rezise/push_back)的许多改变都可能使指向它元素的指针无效。

根据要实现的确切功能,你可以使用这样的类:

#include <vector> 
#include <iostream> 

using namespace std; 

template<class T> 
class Subvector { 
    std::vector<T>*const vec; 
    size_t start; 
    size_t end; 
public: 
    Subvector(std::vector<T>& vector, size_t start, size_t end) : 
     vec(&vector), 
     start(start), 
     end(end) 
    {} 
    size_t size() const { return end - start; } 
    T& operator[](size_t i) { 
     return (*vec)[start + i]; 
    } 
    const T& operator[](size_t i) const { 
     return (*vec)[start + i]; 
    } 
}; 

template<class VEC> 
void printvec(const VEC& v){ 
    for (int i = 0; i < v.size(); i++) { cout << v[i] << " "; } 
    cout << endl; 
} 

int main(){ 
    vector<int> original; 
    for (int i = 1; i <= 10; i++) original.push_back(i); 
    printvec(original); 

    Subvector<int> subvector(original,4, original.size() - 2); 
    subvector[0] = 0; 
    subvector[1] = 0; 
    printvec(subvector); 
    printvec(original); 
    return 0; 
} 
4

如果你不希望使用指针,你可以创建一个slice类转发工作到 - 这将只是一对迭代和任何其他操作,您可能需要:

template <typename T> 
class slice { 
    using iterator = typename T::iterator; 
    using reference = typename std::iterator_traits<iterator>::reference; 

    slice(iterator first, iterator last) 
     : first(first), last(last) 
    { } 

    reference operator[](size_t idx) 
    { 
     return *std::next(first, idx); 
    } 

    iterator begin() const { return first; } 
    iterator end() const { return last; } 

private: 
    iterator first, last; 
}; 

有了这一点,你可以做的正是如此你切片:

slice<vector<int>> subvector(original.begin()+4, original.end()-2); 
    subvector[0]=0; // changes original[4] 
    subvector[1]=0; // changes original[5] 

如果您将printvec更改为采用任意容器并使用range-for迭代它,则也可以打印subvector。它将包含:

0 0 7 8