繁体   English   中英

包含另一个向量的部分子集的向量都指向同一内存

[英]Vector containing a partial subset of another vector both pointing to the same memory

我有一个矩阵类,将其数据存储在std::vector

std::vector<double> mData(mRows*mCols);

该类具有从该矩阵提取列的方法:

std::vector<double> matrix::getCol(const int &n) const
{
    std::vector<double> Col(mRows);

    for(int ii = 0; ii < mRows; ii++)
    {
        Col[ii] = mData[n*mRows + ii];
    }

    return Col;
}

我想让此方法返回对向量的引用,该向量是mData的子集。 这样的事情可能吗?

std::vector<double>& matrix::getCol(const int &n)
{
    std::vector<double> Col(mRows);
    &Col[0] = &mData[n*mRows];

    return Col;
}

我对此感兴趣的原因是我想在分配中使用此方法:

matrix A(rows,cols);
std::vector<double> newCol(rows);
A.getCol(0) = newCol;

一种方法是将矩阵的数据存储到std::vector<std::vector<double> > 然后, matrix::getCol()很简单。

class matrix {
public:
    matrix(int row, int col)
        : mData(col, std::vector<double>(row))
    {
    }
    std::vector<double>& getCol(int n)
    {
        return mData[n];
    }
private:
    std::vector<std::vector<double> > mData;
};

matrix A(rows, cols);
std::vector<double> newCol(rows);
A.getCol(0) = newCol; // works fine

另一种方法是定义matrix::setCol()

另一种方法是写一个array_ref类,它包含一个指向数据和大小,但拥有数据。 它将允许修改元素,但不允许插入或删除。 然后,您可以构造它指向任一子集的规则数组,向量。 对于具有string_ref类的字符串,这实际上是一种相当普遍的做法,它可能引用std::stringchar*char[N] 这将非常简单,并且几乎不需要更改现有的matrix类。

//untested sample
template<class T>
struct array_ref {
    typedef T value_type;
    typedef T& reference;
    typedef T* pointer;
    typedef ptrdiff_t difference_type;
    typedef size_t size_type;
    typedef T* iterator;
    typedef const T* const_iterator;

    array_ref() : data(nullptr), len(0) {}
    array_ref(T* data_, size_t len_) : ptr(data_), len(len_) {}
    T& at(size_t index) {assert_range(index); return ptr[index];}
    const T& at(size_t index) const {assert_range(index); return ptr[index];}
    T* begin() {return ptr;}
    const T* begin() const {return ptr;}
    T* end() {return ptr+len;}
    const T* end() const {return ptr+len;}
    T* data() {return ptr;}
    const T* data() const {return ptr;}
    T& operator[](size_t index) {return ptr[index];}
    const T& operator[](size_t index) const {return ptr[index];}
    size_t size() const {return len;}
private: 
    void assert_range(size_t index) const
    {if (index>=len) throw std::out_of_range("out of range");}
    T* ptr;
    size_t len;
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM