1

以下のコードはコンパイルされません

void aaa(const int **a) {
}

int *a[] = {new int[2]};
aaa(a);

VS2010で「パラメータ1を「int [1]」から「 constint*」に変換できません」とgccで同様のエラーが発生しました

宣言を次のように変更すると、次のようになります。

int const *a[] = {new int[2]};

また

const int *a[] = {new int[2]};

コンパイルされますが、非const変数宣言を受け入れない理由がわかりません

4

2 に答える 2

8

の型aint*[]; あなたが望むタイプはですint const**int*[]に変換されint**ますが、これは暗黙的に に変換されません int const**。理由を理解するには、次のコードを検討してください。

static int const ci = 42;

void aaa( int const** out )
{
    *out = &ci;
}

int
main()
{
    int* pa;
    aaa( &pa );     //  NOT LEGAL, because...
    *pa = 0;        //  would now change ci
    std::cout << ci << std::endl;
    return 0;
}

ご覧のとおり、この変換を許可すると、キャストを必要とせずに const が壊れます。

あなたが何をしているかに応じて、以下を使用したいかもしれません:

void aaa( int const* const* out );

int**toの暗黙的な変換int const *const *は有効です。(それ以外の場合は、自分const_castが何をしているのかを知っていて、実際には問題ではないことをコンパイラに伝えるために、どこかが必要になります。)

于 2012-02-24T09:19:10.240 に答える
2

この関数aaaは、ポインターからポインターへの定数 int を想定しています。あなたの変数aはポインタからポインタへのintです。後者を前者に割り当てるのはエラーです。

とは実際には同じもので、 の署名と一致しint const *a[]ます。を試した場合、それは別の型 (pointer-to-constant-pointer-to-int) になり、型エラーが再びトリガーされます。const int *a[]aaaint * const a[]

aaa関数が定数ポインターからポインターへの int を取りたい場合は、 を記述する必要がありますaaa(int ** const a)が、パラメーター値に const 性を持たせても、実際には呼び出すことができるものには影響しません。


編集: 「しかし、constnessは暗黙的に追加されていません-暗黙のキャストで行われますか?(実際の質問はどれですか)」

Constness は、渡す値に暗黙的に追加できます。

void aaa(const int a) {}

int b=5;
aaa(b);

... または 1 つのレベル ポインター

void aaa(const int* a) {}

int *b=new int;
aaa(b);

...しかし、より深く追加することはできません。たとえば、これは無効です。

void aaa(const int** a) {}

int* b=new int;
int** c=&b;
aaa(c);

ジェームズ・カンゼは、彼の答えでそれをよりよく説明していると思います。

于 2012-02-24T09:11:33.890 に答える