ポインターの逆参照の両方のレベルでコンテンツを保護する必要があります。これによりconst char**
、最初の逆参照で実際にコンテンツを変更できます。
char *tmp = "foo"; //Deprecated but it's ok for the example
void f1(const char** a)
{
a[0] = tmp; //this is legal
a[0][1] = 'x'; //this is not
}
そして、これはおそらく意図したものではありません。次のようになります。
char *tmp = "foo"; //Deprecated but it's ok for the example
void f1(char const* const* a)
{
a[0] = tmp; // this is not legal any more
a[0][1] = 'x'; // this still upsets compiler
}
コンパイラは、このような「部分的に」保護されたポインター型への暗黙的な変換を許可しません。このような変換を許可c++faq
すると、@zmb のコメントで指摘されているように、厄介な結果が生じる可能性があります。この回答では、例を使用して、許可されている場合にオブジェクトのconstnessに違反する方法についても言及していますchar
。
ただし、2番目のコード例に示すように、「完全に」保護されたポインターに暗黙的に変換できるため、以下のコードがコンパイルされます。
void f1(char const* const* a){}
void f2(const char* b){}
int main(int argc, char const *argv[])
{
char* c;
f1(&c); // works now too!
f2(c); // works
return 0;
}
実際、この問題についてはたくさんの質問と回答が横たわっています。例えば:
- 「char**」から「const char**」への無効な変換</a>
- 'float**' を 'const float**' に変換するときにエラーが発生するのはなぜですか?
編集: 最初の例を少し間違えました。ご指摘ありがとうございます!