Передача неконстантного многомерного массива в функцию, которая не меняет его

Возможный дубликат:
почему не разрешено преобразовывать (указатель на указатель на неконстантный) в (указатель на указатель на константный)

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

int doNotChangeA(int const *a){
    return a[0]+3;
}

int doNotChangeC(int const **c){
    return c[0][0]+3;
}

int main(){

    int *a= new int[1];
    a[0]= 5;
    int b= doNotChangeA(a);
    delete []a;

    int **c= new int*[1];
    c[0]= new int[1];
    c[0][0]= 6;
    int d= doNotChangeC(c);
    delete []c[0];
    delete []c;

    return 0;
}

Этот код выдает ошибку компиляции:

cst.cpp:19: error: invalid conversion from ‘int**’ to ‘const int**’
cst.cpp:19: error:   initializing argument 1 of ‘int doNotChangeC(const int**)’

Итак, я немного запутался - почему первая часть (неконстантный одномерный массив, переданный в doNotChangeA) разрешена, а вторая (неконстантный двухмерный массив, переданный в doNotChangeC) не разрешена?

По сути, я хочу, чтобы c было int**, которое указывает на неконстантные значения, поскольку я хочу делать с ним все, что захочу, до и после вызова doNotChangeC. Конечно, я мог бы изменить doNotChangeC так, чтобы он просто принимал int** вместо int const**, и это "решило бы" проблему, но я хочу явно показать, что doNotChangeC не изменяет базовый 2-D массив.

Это то, что нужно сделать:

int d= doNotChangeC( const_cast<int const**>(c) );

Это компилируется нормально, но я запутался, почему это не требуется для первой части, то есть 1-D массива (doNotChangeA)?

Спасибо

1 ответ

Решение

Это должно быть

int doNotChangeC(int const *const *c){
    return c[0][0]+3;
}

Без дополнительного const ваша функция сможет сделать что-то вроде этого:

int doNotChangeC(int const **c){
    c[0] = &something_else;
    return c[0][0]+3;
}

Обратите внимание, что это отличается от того, как работает C. В C вы все равно не сможете пройти int ** к функции, которая принимает int const *const *потому что его правила проще.

Другие вопросы по тегам