在我的代码中,我有一个像这样的双矩阵:
double * * matrix=new double * [10];
for(int i=0;i<10;i++)
matrix[i]=new double[10];
我希望在初始化时,在此矩阵的每个单元格中都有 NaN值,是否可以自动执行或唯一的解决方案是:
for(int i=0;i<10;i++)
for(int j=0;j<10;j++)
matrix[i][j]=nan("");
是否有可能推断出当矩阵将进行结构化时,它不会使用双重插入的默认构造函数,对于每个矩阵[i] [j],0.0值但插入nan(“”)?
答案 0 :(得分:1)
double
没有默认构造函数,即默认情况下double
值未初始化。
为避免显式实现循环,您可以使用std::vector
:
#include <vector>
...
std::vector<std::vector<double>> matrix(10, std::vector<double>(10, nan("")));
或:
#include <vector>
using namespace std;
...
vector<vector<double>> matrix(10, vector<double>(10, nan("")));
答案 1 :(得分:1)
首先,强烈避免自己在C ++中使用原始指针 - 这几乎总是一个坏主意。如果没有适合的容器类,请使用std::unique_ptr
。所以你的代码变成了:
auto matrix = std::make_unique<double* []>(10);
for(int i=0;i<10;i++) {
matrix.get()[i]= std::make_unique<double []>(10);
}
此代码仍然不是您想要的。使用N个new
调用或n个向量构造来创建NxN矩阵通常不是一个好主意。单独分配NxN双精度数,然后将其包装在支持2参数方括号运算符的类MyMatrix
中,即
template <typename T>
class MyMatrix {
// etc. etc
double const T& operator[](size_type i, size_type j) const { return data_[i*n + j]; }
double T& operator[](size_type i, size_type j) { return data_[i*n + j]; }
}
或(不推荐)让指针指向单一分配区域:
size_t n = 10;
auto matrix_data = std::make_unique<double []>(n * n);
auto matrix = std::make_unique<double* []>(n);
for(int i=0;i<10;i++) {
matrix.get()[i] = matrix_data.get() + i * n;
}
在每种情况下,您可以稍后使用std::fill
将所有矩阵值设置为NaN,在任何循环之外。
上面的最后一个例子也可以转换为使用向量(如果你不使用自己的类,这可能比原始指针更好):
size_t n = 10;
auto matrix_data = std::vector<double>(n * n);
auto matrix = std::vector<double*>(n);
for(auto& row : matrix) {
auto row_index = std::dist(row, matrix.begin());
row = &matrix_data[row_index * n];
}
同样,我不建议这样做 - 它仍然是一种类似于C的方式来启用my_matrix[i][j]
语法,而使用包装类可以让你my_matrix[i,j]
而不需要额外的存储,初始化为NaN或其他值(在构造函数中),每次访问时都不会跟随两个指针。
答案 2 :(得分:0)
如果您想使用静态大小的数组,最好使用std::array
。为了更方便地使用多维std::array
,您可以使用模板别名
template <class T, size_t ROW, size_t COL>
using Matrix = std::array<std::array<T, COL>, ROW>;
您可以使用std::array::fill
设置矩阵中的值,例如
Matrix<double, 3, 4> m = {};
m.fill(42.0);
您还可以创建一个使用默认值初始化的编译时常量矩阵对象,以便在运行时使用简单的constexpr
函数跳过初始化。
template<typename T, size_t R, size_t C>
constexpr auto makeArray(T&& x) {
Matrix<T,R,C> m = {};
for(size_t i=0; i != R; ++i) {
for(size_t j=0; j != C; ++j) {
m[i][j] = std::forward<T>(x);
}
}
return m;
}
auto constexpr m = makeArray<double, 3,4>(23.42);
我将重复给出比C结构更喜欢C ++结构的建议。它们更安全,IMHO几乎总是更方便使用,例如传递std::array
个对象作为参数与任何其他对象没有区别。如果您来自C背景并且没有其他C ++经验,我建议您阅读一些不首先介绍C的教程文本,例如: The Tour of C++,