繁体   English   中英

C ++,boost,将对象存储在多维数组中而无需默认构造函数

[英]c++, boost, store objects in multidimensional array without default constructor

我想在一个多维数组中存储数千个插值函数,最好是从boost中获得的函数。 主要问题是我使用的插值函数是一个没有默认构造函数的类。 这禁止我初始化多维数组。

我希望我能做的是:

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

问题在于类Linear_interp没有默认构造函数(该类类似于此类1 ),因此boost :: multi_array无法初始化数组。

请注意,我在循环内初始化了所有插值,因此,我需要存储这些对象。 指向对象的简单指针将不起作用,因为该对象将在每个循环中被覆盖。

实际上,我将拥有更多的尺寸(atm我有10个尺寸),并且multi_array是处理这些尺寸的理想容器。 另外,后面循环中的插值将采用先前循环中的插值(即,我有一个递归问题)。

编辑1:小代码更正。

编辑2:代码更正:在以前的版本中,我没有保存导致不必要结果的“ y”。

我不是专家,但是我确定有一个等效的解决方案。 您可以执行以下步骤:

确保使用最里面的空数组构建一个完整的“矩阵”。 类似于以下内容(使用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或(在C ++ 11中为::push_back )填充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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM