我有这个简单的代码,编译时没有错误/警告:
void f(int&, char**&){}
int main(int argc, char* argv[])
{
f(argc, argv);
return 0;
}
以及下一个无法编译的类似代码:
void f(int&, char**&){}
int main()
{
int argc = 2;
char* argv[] = { "", "", nullptr };
f(argc, argv);
//@VS2013 error: cannot convert argument 2 from 'char *[3]' to 'char **&'
//@GCC error: invalid initialization of non-const reference of type 'char**&' from an rvalue of type 'char**'
return 0;
}
为什么 char*[]
在第一个示例中可以转换为 char**&
而在第二个示例中无法转换?在编译时是否知道大小是否重要?
编辑:我认为第二种情况需要 2 次转换,编译器只能进行一次隐式转换。
这段代码编译得很好:
void f(int&, char**&){}
int main()
{
int argc = 2;
char* temp[] = { "", "", nullptr };
char** argv = temp;
f(argc, argv);
return 0;
}
最佳答案
因为尽管看起来,main
的第二个参数有
键入 char**
。当用作函数的声明时
参数,顶级数组被重写为指针,所以 char
*[]
实际上是 char**
。这仅适用于函数
但是参数。
A char*[]
(如您的第二种情况)可以转换为 char**
,
但是转换的结果(与任何转换一样)是
rvalue,并且不能用于初始化非常量引用。
为什么要引用?如果是修改指针,
将 char**
参数修改为 main
是未定义的行为
(正式地,至少在 C 中——我没有检查 C++ 是否更多
这里是自由的)。当然,你不可能
修改数组的常量地址。如果你不想
要修改它,为什么要使用引用?
关于C++ char*[] 到 char** 的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20467514/