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);