是否有可能将统一初始化和构造函数结合起来?
Is it possible to combine uniform initialization and constructors?
我知道我可以通过使用数组来存储Matrix的数据来做到这一点。
Matrix<2, 2> m = { 1, 2
3, 4 };
但我想用一个向量来代替,因为当矩阵变大,堆栈空间耗尽时,使用数组是非常糟糕的
Matrix m(2, 2) = { 1, 2
3, 4 };
这个(或类似的)可以做到吗?
如果您在编译时有一个固定的大小,但希望使用动态分配,您可以单独选择每个对象的分配类型("stack"/"heap")或将动态分配构建到Matrix
类中。
Matrix
类之外的动态分配示例。注意,使用初始化器列表可以防止在编译时检查传递给actor at的元素的数量(而不是声明Matrix
的contexpr
实例)。因此,我引入了一个相当愚蠢的附加功能来演示编译时大小检查。
#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
,使动态分配成为内置的。
如果在编译时不知道大小,则必须在Matrix
类中构建动态分配(如上所述)。正如您可以推断出2级初始化器列表的大小(列、行)一样,您只需要删除接受固定大小数组的变量,并更改接受1级初始化器列表的变量,如:
template < typename T > // no size parameters!
struct Matrix
{
Matrix(std::size_t columns, std::size_t rows, std::initializer_list<T> p);
Matrix(std::initializer_list< std::initializer_list<T> > p);
// maybe an additional ctor for dynamically allocated arrays
// getters, setters, data members
};
// usage:
Matrix myMatrix0( 2, 2, {1,2,3,4} );
Matrix myMatrix1( {{1,2},{3,4}} );
相关文章:
- "error: no matching function for call to"构造函数错误
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 选择要调用的构造函数
- 如何委托派生类使用其父构造函数?
- 构造函数正在调用一个使用当前类类型的函数
- 没有用于初始化C++中的变量模板的匹配构造函数
- 初始化具有非默认构造函数的std::数组项的更好方法
- 当从函数参数中的临时值调用复制构造函数时
- 在c++构造函数中使用随机字符串生成器
- 一对向量构造函数:初始值设定项列表与显式构造
- 从构造函数抛出异常时如何克服内存泄漏
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 将复制构造函数与 std::make_shared 结合使用
- 与构造函数中rvalue结合的非const lvalue有关的错误
- 所有版本的 GCC 都与默认成员初始值设定项作斗争,该初始值设定项捕获了这一点,并结合了继承的构造函数
- 是否有可能将统一初始化和构造函数结合起来?