C ++新手,并试图绕过initializer_list。
我正在创建一个Matrix类,它有效地存储了一个二维数组的double值。我没有在结构层面上获得这个项目。好的我们制作一个基本上存储2D数据数组的Matrix类。但它需要能够存储任何大小的数组,因此它必须使用动态分配的数组。但是std :: array是不允许的。
我不知道如何访问i_list中的项目。如果他们像
一样传入Matrix a = {{1, 2}, {3, 4}};
然后根据我见过的文档,我在构造函数中与该信息交互的唯一选择是list.begin(),它指向{1,2}和list.end()哪个指向到{3,4}
项目描述禁止使用std :: vector和std :: array,非动态数组显然不能接受大小变量。
那么如何让它能够读取任何大小的矩阵,如何从i_list中获取这些值并将它们存储为非动态的?
我设想像
这样的东西Matrix::Matrix(const initializer_list & list) {
double * mat[/*somehow find out size without dynamic allocation*/];
for (double* i : mat) {
*i = list[i]; //not how i_list works apparently
}
}
项目说明说: 您不能在此项目中使用std :: array,std :: vector,std :: list等库类。您必须使用动态分配的数组
在内部实现Matrix类答案 0 :(得分:3)
initializer_list
是[引用]临时对象的非常便宜的容器。
您可以像对待数组一样迭代它们。此外,他们还有size()
成员,因此您可以查询其大小。
以下是将“2d”initializer_list
传递给函数(可以很容易地构造函数)的示例:
#include <initializer_list>
#include <iostream>
using list_of_doubles = std::initializer_list<double>;
using list_of_list_of_doubles = std::initializer_list<list_of_doubles>;
void info(list_of_list_of_doubles lld)
{
std::cout << "{\n";
for (auto& ld : lld) {
std::cout << " {";
auto sep = " ";
for (auto& d : ld) {
std::cout << sep << d;
sep = ", ";
}
std::cout << " }\n";
}
std::cout << "}\n";
}
int main()
{
info({
{ 1,2,3 },
{ 4.0, 5.0, 6.0 }
});
}
预期产出:
{
{ 1, 2, 3 }
{ 4, 5, 6 }
}
打印出列表的内容非常简单,但是如果我想非动态地保存它们呢?我正在创建一个类构造函数,我希望能够访问这些数据。
好的,所以要求是类中的存储是非动态的(即固定大小)。
我将做一些假设:
这是一种(很多)方式:
#include <initializer_list>
#include <iostream>
#include <stdexcept>
#include <algorithm>
using list_of_doubles = std::initializer_list<double>;
using list_of_list_of_doubles = std::initializer_list<list_of_doubles>;
struct matrix
{
matrix(list_of_list_of_doubles lld)
: _storage {}
{
if (lld.size() > 3)
throw std::invalid_argument("too many rows");
auto row_idx = std::size_t { 0 };
for (auto& row : lld) {
if (row.size() > 3)
throw std::invalid_argument("too many columns");
std::copy(std::begin(row), std::end(row), std::begin(_storage[row_idx]));
++row_idx;
}
}
double _storage[3][3];
};
std::ostream& operator<<(std::ostream& os, const matrix& m)
{
std::cout << "{\n";
for (auto& ld : m._storage) {
std::cout << " {";
auto sep = " ";
for (auto& d : ld) {
std::cout << sep << d;
sep = ", ";
}
std::cout << " }\n";
}
return std::cout << "}";
}
int main()
{
matrix m({
{ 1,2,3 },
{ 4.1, 5.2, 6.3 },
{ 2.01, 4.5 } // ,0
});
std::cout << m << std::endl;
}
但我想要一个动态大小的二维数组...
哦,继续......
#include <initializer_list>
#include <iostream>
#include <algorithm>
#include <numeric>
using list_of_doubles = std::initializer_list<double>;
using list_of_list_of_doubles = std::initializer_list<list_of_doubles>;
std::size_t total_extent(const list_of_list_of_doubles& lld)
{
return std::accumulate(std::begin(lld), std::end(lld), std::size_t(0),
[](auto tot, auto& container) {
return tot + container.size();
});
}
struct matrix
{
using value_storage = std::unique_ptr<double[]>;
using index_storage = std::unique_ptr<std::size_t>;
matrix(list_of_list_of_doubles lld)
: _total_extent { total_extent(lld) }
, _rows { lld.size() }
, _indecies { new std::size_t[_rows] }
, _storage { new double [_total_extent] }
{
auto istorage = _storage.get();
auto iindex = _indecies.get();
for (auto& row : lld) {
*iindex++ = istorage - _storage.get();
istorage = std::copy(std::begin(row), std::end(row), istorage);
}
}
std::size_t rows() const {
return _rows;
}
const double* column(std::size_t row) const {
return std::addressof(_storage[_indecies[row]]);
}
std::size_t column_size(std::size_t row) const {
return row == _rows - 1
? _total_extent - _indecies[row]
: _indecies[row + 1] - _indecies[row];
}
std::size_t _total_extent, _rows;
std::unique_ptr<std::size_t[]> _indecies;
std::unique_ptr<double[]> _storage;
};
std::ostream& operator<<(std::ostream& os, const matrix& m)
{
std::cout << "{\n";
for (std::size_t row = 0 ; row < m.rows() ; ++row) {
std::cout << " {";
auto sep = " ";
for (std::size_t col = 0 ; col < m.column_size(row) ; ++col) {
std::cout << sep << m.column(row)[col];
sep = ", ";
}
std::cout << " }\n";
}
return std::cout << "}";
}
int main()
{
matrix m({
{ 1,2,3 },
{ 4.1, 5.2, 6.3 },
{ 2.01, 4.5 } // ,0
});
std::cout << m << std::endl;
}
答案 1 :(得分:0)
也许,你正在寻找这样的东西:
struct Matrix {
Matrix(std::initializer_list<std::initializer_list<double>> m) {
int max=0;
for (auto l: m)
if (m.size()>max)
max= m.size();
std::cout << "your matriz seems to be: "
<< m.size() << ' ' << max << std::endl;
}
};