在第一维std::vector的std::vector中写入
Writting in a std::vector of std::vectors in the first dimension
我有一个std::vectors
的std::vector
,我想使用for循环将一个元素推回每个内部向量。代码看起来像这样,但显然不能工作,因为您不能以这种方式访问每个向量(matrix[i] =
),并且第8行产生Segmentation Fault
。
std::vector<std::vector<float> > matrix;
for (size_t j = 0; j < number_of_columns; ++j) {
vector<float> elements_to_push = compute_elements();
for (size_t i = 0; i < number_of_rows; ++i) {
matrix[i].push_back(elements_to_push[i]);
}
}
所以,我想按列来写元素。对我来说,逐行编写不是一个选择,因为我需要使用一些期望元素按此顺序编写的外部函数。
我认为解决方案涉及使用指针向量(std::vector<float*>
),但我想知道是否有可能只使用向量,因为这简化了事情。
此外,如果解决方案不涉及c++ 11或更高版本的功能,那将是最好的,因为我必须保持向后兼容性。但是,如果您有一个使用c++ 11或更高版本的答案,您仍然可以为其他可能觉得有用的人编写它。
如果计算和推入行而不是列会更容易。然而,这里有一个解决方案(因为你已经知道矩阵的大小):
std::vector<std::vector<float> > matrix(number_of_rows, std::vector<float>(number_of_columns, float()));
for (size_t j = 0; j < number_of_columns; ++j) {
vector<float> elements_to_push = compute_elements();
for (size_t i = 0; i < number_of_rows; ++i) {
matrix[i][j] = elements_to_push[i];
}
}
我建议在行主配置中围绕单个std::vector
创建一个包装器来表示您的矩阵,使其比2D std::vector
更方便使用。以下应该与c++11之前的版本兼容,这就是为什么我没有使用auto
和其他一些c++11以后的功能…
template<typename Ty>
class matrix {
// enables use of [][] on matrix objects
class proxy_row_vector {
public:
proxy_row_vector(std::vector<Ty>& _vec, std::size_t cols, std::size_t row_ind)
: vec(_vec), columns(cols), row_index(row_ind) {}
const Ty& operator[](std::size_t col_ind) const {
return vec[row_index*columns + col_ind];
}
Ty& operator[](std::size_t col_ind) {
return vec[row_index*columns + col_ind];
}
private:
std::vector<Ty>& vec;
std::size_t row_index;
std::size_t columns;
};
public:
// construct rows*cols matrix with default-inserted Ty instances
explicit matrix(std::size_t rows, std::size_t cols)
: mtx(rows*cols), rows_(rows), cols_(cols) {}
std::size_t rows() const { return rows_; }
std::size_t columns() const { return cols_; }
// used for const [][] access
proxy_row_vector operator[](std::size_t row_ind) const {
return proxy_row_vector(mtx, cols_, row_ind);
}
// used for mutable [][] access
proxy_row_vector operator[](std::size_t row_ind) {
return proxy_row_vector(mtx, cols_, row_ind);
}
// insert a new row at the end
void push_row(const std::vector<Ty>& row_vec) {
for (std::vector<Ty>::iterator it = row_vec.begin(); it < row_vec.end(); ++it)
mtx.push_back(*it);
++rows_;
}
// insert a new column at the end
void push_column(const std::vector<Ty>& col_vec) {
insert_column(cols_, col_vec);
}
// insert a row at indicated position
void insert_row(size_type row_pos, const std::vector<Ty>& row_vec) {
mtx.insert(mtx.begin() + row_pos*cols_, row_vec.begin(), row_vec.end());
++rows_;
}
// insert a column at indicated position
void insert_column(size_type col_pos, const std::vector<Ty>& col_vec) {
for (std::size_t i = 0; i < col_vec.size(); ++i) {
mtx.insert(mtx.begin() + i*(cols_+1)+col_pos,col_vec[i]);
}
++cols_;
}
private:
std::vector<Ty> mtx;
std::size_t rows_;
std::size_t cols_;
};
那么push一个新列就很简单了,使用下面的例子:
matrix<float> mat;
std::vector<float> column_to_push = compute_elements();
mat.push_column(column_to_push);
注意:在上面的matrix
类中,没有边界或大小检查,因为它是此类类的最小示例。您应该在行/列插入方法中添加大小检查,以避免尝试分别推入超过(或少于)当前矩阵的列数或行数的行向量或列向量。此外,你可能想添加迭代器支持(通过std::vector
迭代器微不足道)和其他方法(例如擦除行/列)。
相关文章:
- 使用std::vector的OpenCL矩阵乘法
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- std::vector的包装器,使数组的结构看起来像结构的数组
- 编译器如何区分std::vector的构造函数
- 使用 pqxx 将 std::vector 存储在 postgresql 中,并从数据库中检索它
- 在std::vector上存储带有模板的类实例
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 为什么std::vector比数组慢
- std::vector::迭代器是否可以合法地作为指针
- 如何将二进制格式的 C++ 对象的 std::vector 保存到磁盘?
- 为什么std::vector和std::valarray初始化构造函数不同
- ";结果类型必须是可从输入范围的值类型""构造的;创建std::vector时
- 在没有未定义行为的情况下实现类似std::vector的容器
- 如何调整 std::vector of Eigen::MatrixXd 的大小
- 使用 std::vector::reverse_iterator 将 int 序列化为字节向量?
- 如何将AERT_Allocate与 std:vector 一起使用
- 推导 std::vector::back() 的返回类型
- 如何将原始字节附加到 std::vector?
- std::vector 没有重载函数的实例与参数列表匹配
- 如果 KEY 是 std::list 或 std::vector 而不是值,那么 std::map 的默认行为是什么?