Невозможно преобразовать (*) [] в **

Если я создаю файл:

test.cpp:

void f(double **a) {

}

int main() {
    double var[4][2];
    f(var);
}

И затем запустите: g++ test.cpp -o test

Я получаю

test.cpp: In function `int main()':
test.cpp:8: error: cannot convert `double (*)[2]' to `double**' for argument `1'
 to `void f(double**)'

Почему я не могу этого сделать?

Не является ли double var [4] [2] тем же, что и double ** var, а затем выделяет память?

Ответ 1

Строки С++: [] vs. *

Посмотрите на "Экскурсии: многомерные массивы", в которых описывается, как передавать многомерные массивы в функции в качестве аргументов. В основном вы хотите изменить свой код на это:

// same as void f(double (*a)[2]) {
void f(double a[][2]) { 

}

int main() {
    // note. this is not a pointer to a pointer, 
    // but an array of arrays (4 arrays of type double[2])
    double var[4][2];

    // trying to pass it by value will pass a pointer to its
    // first element 
    f(var);
}

Все вызываемые функции должны быть известны всем, кроме последних. В противном случае, индексируя массив, компилятор не сможет вычислить правильное расстояние до значений в вашем массиве (a [1] находится в sizeof(double[2]) байтах от [0]).

Кажется, вы хотите принять массив без знания размера размеров. Вы можете использовать шаблоны для этого:

template<std::size_t N>
void f(double a[][N]) { 
    // N == 2 for us
}

int main() {
    double var[4][2];
    f(var);
}

Компилятор сделает копию (экземпляр) этого шаблона для каждого значения N, используемого с функцией, автоматически выведя правильный N.

Ответ 2

Проблема заключается в том, что double ** является указателем на указатель. Ваша функция "f" хочет передать адрес указателя на double. Если вы вызываете f (var), ну, где именно вы думаете, что этот указатель? Он не существует.

Это будет работать:

double *tmp = (double *) var;
f (&tmp);

Кроме того, было бы полезно изменить определение f:

void f (double a[4][2]) { }

Теперь f принимает указатель на тип массива, который у вас есть. Это будет работать.