【问题标题】:How to pass a multidimensional array to a function without inner dimension in c++? [duplicate]c++ - 如何将多维数组传递给没有内部维度的函数? [复制]
【发布时间】:2016-01-30 05:57:38
【问题描述】:

我想知道是否有办法说将 double MyArray[][2] = {{0.1,0.8},{0.4,0.6}} 传递给类似 void MyFunction(double myArray[][]); 这样的函数,而不是说 void MyFunction(double myArray[][2]);。我需要这个,因为我希望我的函数能够处理具有不同内部尺寸的数组,例如:double MyArray[][3] = {{0.1,0.8},{0.4,0.6},{0.3,0.9}}。据我所知,要将其传递给函数,我必须将 MyFunctions 的参数更改为 MyFunction(myArray[][3]);。从我读过的内容来看,我不知道这是否可能,所以如果不是,那么还有其他方法吗?

【问题讨论】:

  • 可以选择使用std::vector<std::vector<double> > 吗?
  • 任何可以使这项工作按我想要的方式工作的方法都是一种选择。所以我想是的。
  • C++ 模板就是答案。如果没有模板,你可以只传递double ** MyArray,但是你需要小心,因为函数不知道数组有多大。

标签: c++ arrays function multidimensional-array


【解决方案1】:

如果您可以将MyFunction 更改为:

,您可以通过引用传递任意二维数组
template<std::size_t N, std::size_t M>
void MyFunction(double (&myArray)[N][M]) {
  // ...
}

这样你也可以得到数组的维度。

【讨论】:

  • 你可以有多个模板吗?
  • @MrQandA 在什么情况下?
  • 我想在 MyFunction 中有两个数组。我该怎么做? void MyFunction(double (&amp;W)[N][M],double (&amp;TD)[N][M])?
  • @MrQandA 当然可以。您还可以定义更多模板参数,以便两者也可以是任意维度(例如,template&lt;std::size_t N1, std::size_t M1, std::size_t N2, std::size_t M2&gt; void MyFunction(double (&amp;myArray1)[N1][M1], double (&amp;myArray2)[N2][M2]
  • 如何将 N1 转换为整数?
【解决方案2】:

你可以用模板做到这一点:

template < size_t Dim >
void fun(double (*array)[Dim], size_t outerDim);

在这一点上,虽然我会认真考虑使用std::arraystd::vector

【讨论】:

    【解决方案3】:

    C++ 有动态数组,它们被称为std::vector。您可以使用向量的向量,例如

    typedef std::vector<std::vector<double> > DMatrix;
    

    并像传递任何其他对象一样传递这种类型的对象,即

    void foo(const DMatrix& matrix){
        for (int i=0;i<matrix.size();i++){
            for (int j=0;j<matrix.size();j++){
                std::cout << matrix[i][j] << std::endl;
            }
        }
    } 
    

    【讨论】:

      【解决方案4】:

      这是一个非常常见的问题。

      不幸的是,对于直接数组,您应该以艰难的方式来做。

      首先,您需要一个函数来索引给定适当的索引和维度的多维数组的元素。对于二维数组:

      std::size_t index( std::size_t columns, std::size_t row, std::size_t column )
      {
        return (row * columns) + column;
      }
      

      请注意缺少边界检查。您可以根据需要添加它,但您应该编写不需要它的代码。 (您的函数不应该需要它,而内联辅助函数将帮助您的用户不需要它。)

      接下来,您的函数必须像在 C 中一样工作——获取 扁平化(一维)数组的地址和维度。例如,这里我们将打印一个 const 2D 数组:

      template <typename T>
      void my_fn( const T* a, std::size_t rows, std::size_t columns )
      {
        for (std::size_t r = 0; r < rows; r++)
        {
          for (std::size_t c = 0; c < columns; c++)
          {
            std::cout << a[ index( columns, r, c ) ] << " ";
          }
          std::cout << "\n";
        }
      }
      

      最后,您需要创建一些内联函数,将其转换为对通用函数的调用:

      template <typename T, std::size_t M, std::size_t N>
      inline
      void my_fn( const T (&a)[M][N] )
      {
        return my_fn( (const T*)a, M, N );
      }
      

      现在您可以将它与任何二维数组一起使用:

      int main()
      {
        int xs[5][3];
        my_fn( xs );
      
        double ys[12][7];
        my_fn( ys );
      

      效率考虑:

      • 模板化函数的代码只能为每个类型生成一次同一类型的不同维度都将使用相同的函数。

      • 内联 thunk 应该完全消失 -- 已被编译器优化掉。

      • 寻址元素并不比其他情况复杂,应该自动优化。

      希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 2017-07-15
        • 2011-06-13
        • 1970-01-01
        • 2014-01-15
        • 1970-01-01
        • 1970-01-01
        • 2014-11-19
        • 2014-03-16
        相关资源
        最近更新 更多