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

时间:2011-01-03 14:54:20

标签: c++ c visual-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[][][])
{

}

8 个答案:

答案 0 :(得分:14)

您可以使用模板。

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

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

答案 1 :(得分:5)

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

答案 2 :(得分:3)

您可以使用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.
}

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

另请注意,我通过引用传递数组;你实际上不能按值传递数组,因为参数会折叠成指针,而对于多维数组,这会有点复杂。

希望这有帮助。

答案 3 :(得分:2)

您可以使用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);

答案 4 :(得分:1)

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

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

    马丁。

答案 5 :(得分:1)

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

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

}

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

答案 6 :(得分:0)

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

标题中的

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

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

答案 7 :(得分:0)

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

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

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