问题描述
我正在创建一个名为“matrix”的类,它的类成员为 std::vector<std::vector<T>>
,在类构造函数中设置其大小的最佳优化方法是什么?我在 matrix_.resize(m)
行的构造函数中使用 m
,然后使用 for 循环设置其行值(矩阵 m x n
)。我的问题是:
-
例如,当我使用
std::vector<std::vector<T>> = matrix_;
并使用matrix_.resize(m)
时,matrix_
现在将为“m”个std::vector<T>
对象提供“m”个空格,但是,如果matrix_
不知道其对象的大小(std::vector<T>
),它将如何管理内存?如果每个对象都是 size(1000) 或更大怎么办?
#include <iostream>
#include <vector>
// Matrix of shape m x n,'m' lines and 'n' columns
template <typename T>
class matrix {
private:
typedef T value_type;
typedef std::vector<value_type> row;
std::vector<row> matrix_;
public:
// Default constructor,initializes a matrix of size 1x1,with element 0.
matrix() {
matrix_.resize(1);
row temp = {0};
matrix_[0] = temp;
};
matrix(size_t m,size_t n) {
matrix_.resize(m);
// Appends 'm' rows to the matrix_
for (size_t i = 0; i < m; i++) {
row temp(n); // Creates a row of 'n' columns
matrix_[i] = temp;
}
}
value_type& at (size_t m,size_t n) {
return matrix_[m][n];
}
};
int main() {
matrix<double> first(2,2);
first.at(0,0) = 3.3;
first.at(0,1) = 5.2;
first.at(1,0) = 8.9;
first.at(1,1) = 1.4;
return 0;
}
解决方法
最好的方法是不这样做。向量的向量是个坏主意,尤其是在小尺寸的情况下,因为您希望内存是连续的。
template <typename T>
class matrix {
public:
typedef T value_type; // expose this
private:
std::size_t m_size = 0;
std::size_t n_size = 0
std::vector<T> data;
public:
// Default constructor,initializes a matrix of size 0
matrix():matrix(0,0) {};
// square matrix
explicit matrix(std::size_t n):matrix(n,n) {};
matrix(std::size_t m,std::size_t n):
m_size(m),n_size(n),data(m*n,0)
{}
value_type& operator()(size_t m,size_t n) {
return data[m*n_size + n];
}
value_type const& operator()(size_t m,size_t n) const {
return data[m*n_size + n];
}
};
添加 array_view
或 span
:
template<class It>
struct range {
It b,e;
It begin()const{return b;}
It end()const{return e;}
std::size_t size()const{ return end()-begin(); }
bool empty()const{ return begin()==end(); }
};
template<class T>
struct array_view:range<T*> {
T& operator[](std::size_t i)const{
return this->begin()[i];
}
array_view(T* start,T* finish):range<T*>{ start,finish }{}
array_view():array_view(nullptr,nullptr){}
array_view(T* start,std::size_t length):array_view( start,start+length ) {}
};
我们可以添加
array_view<T> operator[](std::size_t m) {
return {std::addressof(data[m*n_size]),n_size};
}
array_view<T const> operator[](std::size_t m) const {
return {std::addressof(data[m*n_size]),n_size};
}
您现在获得了高效的 matrix[a][b]
语法。 (addressof
只是我偏执。