我知道我可以通过使用数组存储Matrix的数据来做到这一点。
Matrix<2, 2> m = { 1, 2
3, 4 };
但我想这样做并使用向量代替,因为当矩阵变大并且你的堆栈空间不足时使用数组非常糟糕
Matrix m(2, 2) = { 1, 2
3, 4 };
这可以(或类似的东西)完成吗?
答案 0 :(得分:3)
如果你在编译时有一个固定的大小,但是想使用动态分配,你可以单独选择每个对象的分配类型(“stack”/“heap”),也可以在{{{ 1}} class。
Matrix
类之外的动态分配示例。请注意,使用初始化列表会阻止在编译时检查传递给ctor的元素数(除了声明Matrix
contexpr
个实例之外)。因此,我引入了一个相当愚蠢的补充来演示编译时大小检查。
Matrix
在上面的示例中,您可以立即用动态分配的数组替换#include <memory>
#include <iostream>
#include <array>
template < typename T, std::size_t rows, std::size_t columns >
struct Matrix
{
public:
Matrix(std::initializer_list<T> p)
{
if(p.size() != rows*columns) { /* throw */ }
std::copy( p.begin(), p.end(), storage_member.begin() );
}
Matrix(std::array<T, columns*rows> const& p)
{
std::copy( p.begin(), p.end(), storage_member.begin() );
}
Matrix(std::initializer_list< std::initializer_list<T> > p)
{
if(p.size() != rows) { /* throw */ }
auto itRow = p.begin();
for(std::size_t row = 0; row < rows; ++row, ++itRow)
{
if(itRow->size() != columns) { /* throw */ }
auto itCol = itRow->begin();
for(std::size_t col = 0; col < columns; ++col, ++itCol)
{
storage_member[col+row*columns] = *itCol;
}
}
}
Matrix(std::array<std::array<T, columns>, rows> const& p)
{
for(std::size_t row = 0; row < rows; ++row)
{
for(std::size_t col = 0; col < columns; ++col)
{
storage_member[col+row*columns] = p[row][col];
}
}
}
// getters, setters
T& operator() (std::size_t row, std::size_t col)
{
return storage_member[col+row*columns];
}
private:
// storage, e.g.
std::array<T, columns*rows> storage_member;
};
template < typename T, typename... TP>
constexpr std::array<T,sizeof...(TP)+1> m(T&& p, TP... pp)
{
return {{p, pp...}};
}
// usage:
int main()
{
using My_Matrix_Type = Matrix < int, 2, 2 >;
std::unique_ptr < My_Matrix_Type > pmyMatrix0{ new My_Matrix_Type( {1,2,3,4} ) };
std::unique_ptr < My_Matrix_Type > pmyMatrix1{ new My_Matrix_Type( {{1,2},{3,4}} ) };
// with compile-time size checks
std::unique_ptr < My_Matrix_Type > pmyMatrix2{ new My_Matrix_Type( m(1,2,3,4) ) };
std::unique_ptr < My_Matrix_Type > pmyMatrix3{ new My_Matrix_Type( m(m(1,2), m(3,4)) ) };
// a more fancy but possible syntax, would require some additional effort:
//std::unique_ptr < My_Matrix_Type > pmyMatrix4{ new My_Matrix_Type( b(1,2)(3,4) ) };
std::cout << (*pmyMatrix0)(1,1) << std::endl;
std::cout << (*pmyMatrix1)(1,1) << std::endl;
std::cout << (*pmyMatrix2)(1,1) << std::endl;
std::cout << (*pmyMatrix3)(1,1) << std::endl;
}
以使内置动态分配。
如果在编译时不知道大小,则必须在storage_member
类中构建动态分配(如上所述)。由于您可以推断出2级初始化列表的大小(列,行),您只需删除采用固定大小数组的ctors并更改ctor采用1级初始化列表,如:
Matrix