c ++,boost,在没有默认构造函数的情况下将对象存储在多维数组中
c++, boost, store objects in multidimensional array without default constructor
我想在一个多维数组中存储数千个插值函数,最好是来自 boost 的那个。主要问题是我使用的插值函数是 class 没有默认构造函数。这禁止我初始化多维数组。
我希望我能做什么:
double func(const double& x1, const double& x2, const double& x3)
{
return x1 + x2 + x3;
};
int main()
{
std::vector<double> x1 {0, 1, 2, 3};
std::vector<double> x2 {1.1, 1.2, 1.3, 1.4, 1.5};
std::vector<double> x3 {0, 10, 20, 30, 40};
std::vector<double> y(20, std::vector<double>(5));
boost::multi_array<Linear_interp, 2> Storage(boost::extents[4][5]);
typedef std::vector<double>::size_type vd_sz;
int n = 0;
for (vd_sz i_x1 = 0; i_x1 < x1.size(); ++i_x1) {
for (vd_sz i_x2 = 0; i_x2 < x2.size(); ++i_x2) {
for( vd_sz i_x3 = 0; i_x3 < x3.size(); ++i_x3) {
y[n][i_x3] = func(x1[i_x1], x2[i_x2], x3[i_x3]);
}
Linear_interp myInterp(x3, y);
Storage[i_x1][i_x2] = myInterp;
++n;
}
}
// Sample usage
double z = Storage[3][2].interp(23);
return 0;
}
问题是 class Linear_interp 没有默认构造函数(class 类似于 class 1),因此 boost::multi_array 无法初始化数组。
请注意,我在一个循环内初始化了所有插值,因此,我需要存储这些对象。指向该对象的简单指针将不起作用,因为该对象将在每个循环中被覆盖。
实际上,我会有更多的维度(atm 我有 10 个),multi_array 是一个很好的容器来处理这些。此外,后面循环中的插值将从前面的循环中进行插值(即我有一个递归问题)。
编辑 1:次要代码更正。
编辑 2:代码更正:在以前的版本中,我没有保存 "y" 导致不需要的结果。
我不是提升专家,但我确信有等效的解决方案。您可以执行以下步骤:
确保构建一个完整的 "matrix",最里面的数组是空的。类似于以下内容(使用 std::vector
)适用于 3
维度:
std::vector<std::vector<std::vector<Linear_interp>>> Storage;
Storage.resize(x1.size());
for (vd_sz i_x1 = 0; i_x1 < x1.size(); i_x1++) {
Storage[i_x1].resize(x2.size());
}
此时,Storage[i][j]
已存在,但为空 std::vector<Linear_interp>
。所以现在你可以使用 std::vector::emplace_back
或(::push_back
with C++11)来填充你的 Storage
。回到二维和你的原始代码,像这样的东西就可以完成工作:
typedef std::vector<double>::size_type vd_sz;
for (vd_sz i_x1 = 0; i_x1 < x1.size(); i_x1++) {
for (vd_sz i_x2 = 0; i_x2 < x2.size(); i_x2++) {
for( vd_sz i_x3 = 0; i_x3 < x3.size(); i_x3++) {
y[i_x3] = func(x1[i_x1], x2[i_x2], x3[i_x3]);
}
Storage[i_x1][i_x2].emplace_back(x3, y);
// or: Storage[i_x1][i_x2].push_back(Linear_interp(x3, y));
}
}
使用 push_back
或类似的方法,只会调用一个复制函数,因此适用于您的非默认构造类型 Linear_interp
.
好的指针会起作用。如果您将数组声明为:
multi_array<Linear_interp*, 2>
存储指向对象的指针而不是对象本身。
然后在循环中,您可以在每次需要时分配新对象并将其放在数组中的适当位置。只需使用 new 关键字在循环内创建新的 Linear_interp 对象。这是在循环内使用的代码:
Storage[i_x1][i_x2] = new Linear_interp(x3, y);
我想在一个多维数组中存储数千个插值函数,最好是来自 boost 的那个。主要问题是我使用的插值函数是 class 没有默认构造函数。这禁止我初始化多维数组。
我希望我能做什么:
double func(const double& x1, const double& x2, const double& x3)
{
return x1 + x2 + x3;
};
int main()
{
std::vector<double> x1 {0, 1, 2, 3};
std::vector<double> x2 {1.1, 1.2, 1.3, 1.4, 1.5};
std::vector<double> x3 {0, 10, 20, 30, 40};
std::vector<double> y(20, std::vector<double>(5));
boost::multi_array<Linear_interp, 2> Storage(boost::extents[4][5]);
typedef std::vector<double>::size_type vd_sz;
int n = 0;
for (vd_sz i_x1 = 0; i_x1 < x1.size(); ++i_x1) {
for (vd_sz i_x2 = 0; i_x2 < x2.size(); ++i_x2) {
for( vd_sz i_x3 = 0; i_x3 < x3.size(); ++i_x3) {
y[n][i_x3] = func(x1[i_x1], x2[i_x2], x3[i_x3]);
}
Linear_interp myInterp(x3, y);
Storage[i_x1][i_x2] = myInterp;
++n;
}
}
// Sample usage
double z = Storage[3][2].interp(23);
return 0;
}
问题是 class Linear_interp 没有默认构造函数(class 类似于 class 1),因此 boost::multi_array 无法初始化数组。
请注意,我在一个循环内初始化了所有插值,因此,我需要存储这些对象。指向该对象的简单指针将不起作用,因为该对象将在每个循环中被覆盖。
实际上,我会有更多的维度(atm 我有 10 个),multi_array 是一个很好的容器来处理这些。此外,后面循环中的插值将从前面的循环中进行插值(即我有一个递归问题)。
编辑 1:次要代码更正。
编辑 2:代码更正:在以前的版本中,我没有保存 "y" 导致不需要的结果。
我不是提升专家,但我确信有等效的解决方案。您可以执行以下步骤:
确保构建一个完整的 "matrix",最里面的数组是空的。类似于以下内容(使用 std::vector
)适用于 3
维度:
std::vector<std::vector<std::vector<Linear_interp>>> Storage;
Storage.resize(x1.size());
for (vd_sz i_x1 = 0; i_x1 < x1.size(); i_x1++) {
Storage[i_x1].resize(x2.size());
}
此时,Storage[i][j]
已存在,但为空 std::vector<Linear_interp>
。所以现在你可以使用 std::vector::emplace_back
或(::push_back
with C++11)来填充你的 Storage
。回到二维和你的原始代码,像这样的东西就可以完成工作:
typedef std::vector<double>::size_type vd_sz;
for (vd_sz i_x1 = 0; i_x1 < x1.size(); i_x1++) {
for (vd_sz i_x2 = 0; i_x2 < x2.size(); i_x2++) {
for( vd_sz i_x3 = 0; i_x3 < x3.size(); i_x3++) {
y[i_x3] = func(x1[i_x1], x2[i_x2], x3[i_x3]);
}
Storage[i_x1][i_x2].emplace_back(x3, y);
// or: Storage[i_x1][i_x2].push_back(Linear_interp(x3, y));
}
}
使用 push_back
或类似的方法,只会调用一个复制函数,因此适用于您的非默认构造类型 Linear_interp
.
好的指针会起作用。如果您将数组声明为:
multi_array<Linear_interp*, 2>
存储指向对象的指针而不是对象本身。 然后在循环中,您可以在每次需要时分配新对象并将其放在数组中的适当位置。只需使用 new 关键字在循环内创建新的 Linear_interp 对象。这是在循环内使用的代码:
Storage[i_x1][i_x2] = new Linear_interp(x3, y);