是否可以组合统一初始化和构造函数?

时间:2013-04-13 21:54:54

标签: c++

我知道我可以通过使用数组存储Matrix的数据来做到这一点。

Matrix<2, 2> m = { 1, 2
                   3, 4 };

但我想这样做并使用向量代替,因为当矩阵变大并且你的堆栈空间不足时使用数组非常糟糕

Matrix m(2, 2) = { 1, 2
                   3, 4 };

这可以(或类似的东西)完成吗?

1 个答案:

答案 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