C ++:没有匹配函数调用构造函数?

时间:2011-10-12 01:55:58

标签: c++ constructor syntax-error

这是我正在使用的构造函数的声明:

_Task Multiplier {
    int **Z;
    int **X;
    int **Y;
    int xr, xcols_yrows, yc;
    void main() {
        for( int i = 0; i < xcols_yrows; i++ ) {
            matrixmultiply(Z, X, xr, i, Y, yc);
        }
    }

  public:
    Multiplier( int *Z[], int *X[], int *Y[], int xr, int xcols_yrows, int yc) :
        Z( Z ), X( X ), Y( Y ), xr( xr ), xcols_yrows( xcols_yrows ), yc( yc ) {}

};

以下是使用它的地方:

int xrows, xcols_yrows, ycols;
// [cols][rows]
int X[xrows][xcols_yrows], Y[xcols_yrows][ycols], Z[xrows][ycols];
// start threads to multiply rows
Multiplier *multipliers[xrows];
for( int r = 0; r < xrows; r++ ) {
    multipliers[r] = new Multiplier( &Z, &X, &Y, r, xcols_yrows, ycols );
}

(它们都已初始化) 但我得到了这个奇怪的错误:

q3.cc: In member function 'virtual void uMain::main()':
q3.cc:132: error: no matching function for call to 'Multiplier::Multiplier(int (*)[(((unsigned int)(((int)xrows) + -0x00000000000000001)) + 1)][(((unsigned int)(((int)ycols) + -0x00000000000000001)) + 1)], int (*)[(((unsigned int)(((int)xrows) + -0x00000000000000001)) + 1)][(((unsigned int)(((int)xcols_yrows) + -0x00000000000000001)) + 1)], int (*)[(((unsigned int)(((int)xcols_yrows) + -0x00000000000000001)) + 1)][(((unsigned int)(((int)ycols) + -0x00000000000000001)) + 1)], int&, int&, int&)'
q3.cc:37: note: candidates are: Multiplier::Multiplier(int**, int**, int**, int, int, int, UPP::uAction)
q3.cc:26: note:                 Multiplier::Multiplier(Multiplier&)
make: *** [q3.o] Error 1

2 个答案:

答案 0 :(得分:2)

问题是函数参数XYZ基本上期望array of pointers to int,但你给它pointer to an array of arrays of int。< / p>

将参数指定为数组(使用[]声明)会衰减为将参数声明为指针。这没关系,因为数组变量基本上可以作为指向数组第一个元素的指针。

这对于n维数组无效,因为编译器需要知道数组沿第二维的宽度,以便计算沿第一维的下一个元素的开始...即,为了知道内存X[1][0]中的哪个位置引用,编译器需要知道X[0]中有多少个元素。

一种解决方案是使用指向每个矩阵开头的指针,并自己进行地址计算。如:

Multiplier( int *Z, int *X, int *Y, int xr, int xcols_yrows, int yc) :
    Z( Z ), X( X ), Y( Y ), xr( xr ), xcols_yrows( xcols_yrows ), yc( yc ) {}
// ...
multipliers[r] = new Multiplier( &Z[0][0], &X[0][0], &Y[0][0], r, xcols_yrows, ycols );

并且知道调用代码中的X[i][j]实际上是X[i*xcols_yrows+j]内的Multiplier

答案 1 :(得分:1)

参数声明int *Z[]指定一个指向整数的指针数组。成员声明int **Z指定指向指针(或其数组)的指针。参数类型int X[xrows][xcols_yrows]是一个多维数组,根本没有指针。

此外,分配的存储位于堆栈中,它将在return语句后消失。由于Multiplier对象分配有new,因此大概应该具有相似的生命周期。可能该数组应由new中的Multiplier::Multiplier分配,或者在任何情况下都应由unique_ptrauto_ptr对象管理。

第一个问题有几种解决方案:

  1. 使用模板化构造函数,该构造函数在编译时检测数组的大小。
  2. 使用由newcalloc分配的指针数组。
  3. 分配一维数组并以多维方式使用它。