将 carray 转换为 initializer_list for istream
Converting carray to initializer_list for istream
我需要从流中读取数组元素,并且我有 std::initializer_list<double>
作为构造函数。我找不到与此相关的任何内容。是否可以从输入流中读取 carray
个元素?我必须在 Vector
class 中定义变量:
double* data
和 size_t rows_
我的代码如下;
构造函数
Vector::Vector(std::initializer_list<double> il) : data(nullptr){`
rows_ = l.size();
data = new double[rows_];
std::copy(il.begin(), il.end(), data);
}
istream 的友元函数
std::istream& operator >>(std::istream &inputStream, Vector& m) {
double *buff = new double[m.rows_];
for (size_t i=0; i !=m.rows_; ++i)
is >> buff[i];
// buff (array) --> initializer_list as "init_list"
m = Vector(init_list);
delete []buff;
return inputStream;
}
class std::initializer_list<T>
是一只相当特别的野兽。它本质上公开了一系列 T
值,以某种方式以可迭代的形式位于内部堆栈中。创建这样一个实体的唯一方法是将值直接放在 std::initializer_list<T>
中。无法创建元素数量可变的 std::initializer_list<T>
。
我的建议是为您的 Vector
class 配备一个采用迭代器的构造函数,例如:
class Vector
{
std::unique_ptr<double[]> buff = 0;
int size = 0;
int capacity = 0;
public:
template <typename InIt>
Vector(InIt begin, InIt end) {
for (auto it = begin; it != end; ++it) {
if (size == capacity) {
capacity = std::max(16, 2 * capacity);
std::unique_ptr<double[]> tmp(new double[capacity]);
std::copy(buff.get(), buff.get() + size, tmp.get());
buff = std::move(tmp);
}
buff[size++] = *it;
}
}
// ...
};
与capacity
的舞蹈是为了避免在序列很大的情况下操作的复杂性:一次增加数组一个元素(或任何固定数字n
)会二次复杂度。以常数因子增加阵列的方法导致线性复杂度。理论上,您可以确定序列的长度 (std::distance(begin, end)
),但对于可以 消耗 序列的输入迭代器。
一旦该构造函数就位,您就可以像这样使用流迭代器读取输入:
Vector(std::istream& in)
: Vector(std::istream_iterator<double>(std::cin),
std::istream_iterator<double>()) {
}
我需要从流中读取数组元素,并且我有 std::initializer_list<double>
作为构造函数。我找不到与此相关的任何内容。是否可以从输入流中读取 carray
个元素?我必须在 Vector
class 中定义变量:
double* data
和 size_t rows_
我的代码如下;
构造函数
Vector::Vector(std::initializer_list<double> il) : data(nullptr){`
rows_ = l.size();
data = new double[rows_];
std::copy(il.begin(), il.end(), data);
}
istream 的友元函数
std::istream& operator >>(std::istream &inputStream, Vector& m) {
double *buff = new double[m.rows_];
for (size_t i=0; i !=m.rows_; ++i)
is >> buff[i];
// buff (array) --> initializer_list as "init_list"
m = Vector(init_list);
delete []buff;
return inputStream;
}
class std::initializer_list<T>
是一只相当特别的野兽。它本质上公开了一系列 T
值,以某种方式以可迭代的形式位于内部堆栈中。创建这样一个实体的唯一方法是将值直接放在 std::initializer_list<T>
中。无法创建元素数量可变的 std::initializer_list<T>
。
我的建议是为您的 Vector
class 配备一个采用迭代器的构造函数,例如:
class Vector
{
std::unique_ptr<double[]> buff = 0;
int size = 0;
int capacity = 0;
public:
template <typename InIt>
Vector(InIt begin, InIt end) {
for (auto it = begin; it != end; ++it) {
if (size == capacity) {
capacity = std::max(16, 2 * capacity);
std::unique_ptr<double[]> tmp(new double[capacity]);
std::copy(buff.get(), buff.get() + size, tmp.get());
buff = std::move(tmp);
}
buff[size++] = *it;
}
}
// ...
};
与capacity
的舞蹈是为了避免在序列很大的情况下操作的复杂性:一次增加数组一个元素(或任何固定数字n
)会二次复杂度。以常数因子增加阵列的方法导致线性复杂度。理论上,您可以确定序列的长度 (std::distance(begin, end)
),但对于可以 消耗 序列的输入迭代器。
一旦该构造函数就位,您就可以像这样使用流迭代器读取输入:
Vector(std::istream& in)
: Vector(std::istream_iterator<double>(std::cin),
std::istream_iterator<double>()) {
}