我有一个矩阵类,可以将其数据存储在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;
答案 0 :(得分:2)
一种方法是将矩阵的数据存储到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()
。
答案 1 :(得分:2)
另一种方法是编写一个array_ref
类,其中包含指向数据和大小的指针,但不拥有数据。它允许修改元素,但不允许插入或删除。然后你可以构造它以指向任何子集的常规数组,向量。对于具有string_ref
类的字符串,这实际上是一种相当常见的做法,可能会引用std::string
,char*
或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;
};