如何使函数在C ++中接收任意大小的多维数组?

时间:2011-03-01 16:26:43

标签: c++ function multidimensional-array arguments

我试图创建一个以矩阵作为输入并在C ++中输出它的某些功能的函数。但我希望它能在任意大小的mxn矩阵上工作。即我不能在函数的参数中指定n的值(double matrix [] [n])。因为n会是任意的。 有什么方法可以将任意mxn 2维数组传递给函数吗? 提前感谢你。 -indiajoe

4 个答案:

答案 0 :(得分:7)

template <typename T, size_t W, size_t H>
void foo(T (&array)[W][H]) {
   // Do stuff with array here
}

答案 1 :(得分:2)

有多种方法可以做到这一点。最好的方法可能是定义矩阵类并将const引用传递给实例。

class matrix
{
    double* values;
    size_t m;
    size_t n;
public:
    matrix(size_t m_, size_t n_)
    : m(m_), n_(n)
    {
        values = new double[m * n];
    }

    ~matrix()
    {
        delete[] values;
    }

    double& operator(size_t i, size_t j)
    {
        assert(i < m);
        assert(j < n);
        return values[i + m * j];
    }

    const double& operator(size_t i, size_t j) const
    {
        assert(i < m);
        assert(j < n);
        return values[i + m * j];
    }
private:
    matrix(const matrix&);
    matrix& operator =(const matrix&);
};

void function(const matrix& matrix);

如果您不想使用类,并且您的数据以线性方式存储(如在我的矩阵类中),您只需将指针传递给double和维度:

void function(double* values, size_t m, size_t n);

如果你真的想使用double [m] [n]并且函数接受任何矩阵大小,你可以手动将它转换为双**,通过这样做:

void function(double** lines, size_t m, size_t n);

void client()
{
    const size_t m = ...;
    const size_t n = ...;
    double matrix[m][n];

    double* temporary[m];
    for (size_t i = 0; i < m; ++ i) {
        temporary[i] = &matrix[i][0];
    }

    function(temporary, m, n);
}

或者,使用模板函数进行转换:

void function(double** array, size_t m, size_t n);

template < size_t M, size_t N >
void function(double array[M][N]) {
    double* temporary[M];
    for (size_t i = 0; i < M; ++ i) {
        temporary[i] = &array[i][0];
    }
    function(temporary, M, N);
}

这是因为一个数组只能衰减一次到一个指针(即双[n]衰减到双*但双[m] [n]衰减到双* [n])。

答案 2 :(得分:1)

使用标准C ++库,您可以这样做:

typedef std::vector<double> Dim;
typedef std::vector<Dim> Matrix;

void workOnMatrix(Matrix& matrix)
{

}

编辑:我删除了对 STL 的引用,因为SGI的 STL 标准C ++库不是一回事。似乎有很多不同,它们似乎不能一个接一个。

答案 3 :(得分:0)

你可以做到Tomalak的方式,但我当然不会推荐它。如果数组通过params传递,你永远不能从另一个也不是模板的函数中调用该函数。这意味着几乎整个程序都必须是模板化代码。好的,理论上,但通常是不切实际的。

您找不到double**界面。您可以转换为该类型,但是您还需要传入大小信息,以便您可以:

my_ptrptr[row * col_size][col];

你必须明确这样的维度,因为编译器不再知道它需要什么。

问题的最佳答案是不这样做。利用STL,这样你就不必像这样处理好事。使用Stephane的答案。

你可以做的另一件事,如果你打算使用模板,就是把它写成通用的:

template < typename Iter >
void fun(Iter begin, Iter end)
{
  // begin[x][y]... (*begin)[y]...++begin, etc...
}
...
double arr[arr_row_count][arr_col_count];
fun(arr, arr+arr_row_count);

这个使用ANYTHING的主要好处就像一个数组数组。这意味着它可以制作一个出色的“临时”方法,您可以将其与double[][]类型一起使用,直到您可以开始使用更好的方式,例如std::vector和/或boost::array。做Tomalak的方式,你将无法在以后做出这种改变......这是另一个不使用该方法的原因。