在C ++中,当char**
转换为const char**
时,为什么无法将char*
作为参数传递给接受const char*
的函数,如下图所示
void f1(const char** a)
{
}
void f2(const char* b)
{
}
int main(int argc, char const *argv[])
{
char* c;
f1(&c); // doesn't work
f2(c); //works
return 0;
}
编译器输出
test.cpp: In function 'int main(int, const char**)': test.cpp:15:10: error: invalid conversion from 'char**' to 'const char**' [-fpermissive] test.cpp:1:6: error: initializing argument 1 of 'void f1(const char**)' [-fpermissive]
答案 0 :(得分:23)
您需要在指针的两个取消引用级别上保护内容。使用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
}
编译器不允许隐式转换为此类“部分”受保护的指针类型。允许这种转换可能会产生令人讨厌的后果,如{@ 3}中所述,@ zmb评论中指出。此c++faq
还引用了如果使用char
示例,如果允许,您如何违反对象的 constness 。
然而,可以隐式转换为“完全”受保护的指针,如第二个代码示例所示,因此在代码编译之下。
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;
}
实际上,这个问题上有很多问题和答案。 E.g: