26

在 C++ 中,为什么不能将 achar**作为参数传递给接受 的函数,而const char**char*to的转换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:在函数'int main(int,const char**)'中:
test.cpp:15:10:错误:从 'char**' 到 'const char**' 的无效转换 [-fpermissive]
test.cpp:1:6: 错误:初始化 'void f1(const char**)' [-fpermissive] 的参数 1
4

1 回答 1

26

您需要在指针的两个取消引用级别上保护内容。您实际上可以在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 在评论中指出的那样,允许这种转换可能会产生令人讨厌的后果。这个答案还使用示例引用了如果允许的话,你怎么能违反对象的常量性。char

但是,可以隐式转换为“完全”受保护的指针,如第二个代码示例所示,因此下面的代码可以编译。

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;
}

实际上,关于这个问题有很多问题和答案。例如:

  1. 从 'char**' 到 'const char**' 的无效转换</a>
  2. 为什么将“float**”转换为“const float**”时出现错误?

编辑:我把第一个例子弄错了一点。感谢您指出!

于 2013-08-16T12:57:08.620 回答