繁体   English   中英

在C ++中将不同大小的常量数组作为函数参数传递

[英]Passing constant Arrays with different sizes as function parameters in C++

我有不同大小的恒定多维数组。 我想将它们传递给一个函数。 但是,我会得到错误的下标,数组的大小不同所以我不能把下标放在数组参数中。 这个问题的解决方案是什么?

这是一个示例代码。 实际的数组更大。

//ARRAY1
const double ARRAY1[3][2][2] =
{
    {
        {1.0,1.0},
        {1.0,1.0},
    }
    ,
    {
        {1.0,1.0},
        {1.0,1.0},
    }
    ,
    {
        {1.0,1.0},
        {1.0,1.0},
    }
}
//ARRAY2
const double ARRAY2[2][2][2] =
{
    {
        {1.0,1.0},
        {1.0,1.0},
    }
    ,
    {
        {1.0,1.0},
        {1.0,1.0},
    }
}

//How to declare the parameter?
double SomeFunctionToWorkWithBothArrays(const double arr[][][])
{

}

你可以使用一个模板。

template<size_t first, size_t second, size_t third> 
double SomeFunction(const double (&arr)[first][second][third]) {
    return first + second + third;
}

此函数引用三维双精度数组,其中所有维在编译时都是已知的。 如果绝望,实际上可以通过模板获取此参考。

使用std::vector而不是数组。 向量知道自己的大小,所以这没有问题。 您可以使用矢量矢量作为多维数组。

您可以使用std::vector (其大小是可变的,不需要在类型中指定),或者您可以坚持使用静态分配并使用模板:

template <size_t X, size_t Y, size_t Z>
double SomeFunctionToWorkWithBothArrays(const double (&arr)[X][Y][Z])
{
   // A different version of this function will
   // exist for each combination of X, Y and Z.
}

(在这个例子中,我假设所有三个维度可能不同。)

另请注意,我通过引用传递数组; 你实际上不能按值传递数组,作为参数会坍缩成一个指针,并与多维数组这变得有点复杂。

希望这可以帮助。

您可以使用boost :: array模板类和模板函数声明来处理此问题。

编辑:只是添加一个例子:

template<typename T, std::size_t I, std::size_t J, std::size_t K>
void MyFunction(const std::array<std::array<std::array<T, K>, J>, I>& data)
{
    // do something here
}

您可以通过以下方式致电:

std::array<std::array<std::array<T, 4>, 2>, 3> data; // which hopefully you have typedef'd somewhere to make the code more readable
MyFunction<double, 3, 2, 4>(data);

我知道这个问题的两种方法:

  1. 使用sentinel值作为数组的最后一个条目,例如。 {-1.0,-1.0}。 您始终只需要检查下一个主要维度中的第一个值
  2. 向函数添加附加参数,该参数指定尺寸的大小,例如。 x,y,z或struct dim { int x, y, z};

问候,

马丁。

如果它只是第一个可变的维度(其他维度对于所有数组都相同),那么您仍然可以将数组传递给同一个函数,因为您可以将第一个数组维度保留在函数参数中。

double SomeFunctionToWorkWithBothArrays(const double arr[][2][2])
{

}

如果其他维度也可以更改,那么您将必须使用可能从单个模板创建的不同功能,如@DeadMG的答案所示。

在C语言中,只需将您的函数定义为

double func (size_t x, size_t y, size_t z, double arr[x][y][z])

这是可能的,因为C(与C ++不同)具有可变长度数组。

当且仅当标准定义了多维数组的排列时(标准大师的问题),您可以执行以下操作:

在你的标题中:

double SomeFunctionToWorkWithBothArraysInt(double const *data, int x, int y, int z);

template <size_t X, size_t Y, size_t Z>
double SomeFunctionToWorkWithBothArrays(double const (&arr)[X][Y][Z]) {
  SomeFunctionToWorkWithBothArraysInt(&arr, X, Y, Z);
}

在.cpp文件中:

double SomeFunctionToWorkWithBothArraysInt(double const *data, int x, int y, int z) {
  double res = 0.0;
  for (int xp = 0; xp < x; xp++) {
    for (int yp = 0; yp < y; yp++) {
      for (int zp = 0; zp < z; zp++) {
        res += data[(zp * y + yp) * x + xp]; // !!!ATTENTION!!!: This may be wrong if the array arrangement is different!
      }  
    }  
  }

  return res;
}

优点是您的“业务逻辑”不会通过模板函数的每个实例化进行实例化,也不会通过头文件公开。

暂无
暂无

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

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