3

重複の可能性:
(非 const へのポインターへのポインター) を (const へのポインターへのポインター) に変換することが合法ではない理由

入力として 2D 配列を受け取り、基になる値を変更しない関数を作成しています。これを関数宣言で明示的に指定したいと考えていました。私はこのコードについて少し混乱しています(これは明らかに私の質問を説明するための最小限のダミーコードです):

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 に渡される非 const 1D 配列) が許可され、2 番目の部分 (doNotChangeC に渡される非 const 2D 配列) が許可されないのはなぜですか?

基本的に私がやりたいことは、doNotChangeC を呼び出す前と後に何でもしたいので、非 const 値を指す c を int** にすることです。もちろん、doNotChangeC を変更して、int const** の代わりに int** を受け取るように変更することもできます。これにより、問題は「修正」されますが、doNotChangeC が基になる 2 次元配列を変更しないことを明示的に示したいと思います。

正しいことは次のとおりです。

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

これは正常にコンパイルされますが、最初の部分、つまり 1-D array (doNotChangeA) でこれが必要ない理由がわかりません。

ありがとう

4

1 に答える 1

2

これはする必要があります

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 **を受け取る関数にan を渡すことはできません。int const *const *

于 2012-12-31T16:53:33.633 に答える