簡體   English   中英

子矢量修改原始矢量

[英]sub-vector modifies original vector

我想提取一個子矢量。 然后修改影響原始矢量的元素。 我的示例代碼如下:

#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;
}

在上面的代碼中,子向量不會修改向量。 有人能指出一種優雅的方法來制作一個修改原始矢量的子矢量(如果可能的話,希望沒有明確使用指針)。

如果你不想使用指針,你可以創建一個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 

這條線:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM