C++ char*[] 到 char** 的转换 [英] C++ char*[] to char** conversion
问题描述
我有这个简单的代码,可以在没有错误/警告的情况下进行编译:
I have this simple code that compiles without errors/warnings:
void f(int&, char**&){}
int main(int argc, char* argv[])
{
f(argc, argv);
return 0;
}
以及下一个无法编译的类似代码:
And next similar code that doesn't compile:
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**&
而在第二个示例中不能转换?在编译时知道大小是否重要?
Why char*[]
can be converted to char**&
in the first sample and can't be converted in the second sample? Does it matter if the size is known at compile time?
我认为在第二种情况下需要进行 2 次转换,编译器只能完成一次隐式转换.
I think there are 2 conversions needed in the second case, and only one implicit conversion can be done by compiler.
这段代码编译得很好:
void f(int&, char**&){}
int main()
{
int argc = 2;
char* temp[] = { "", "", nullptr };
char** argv = temp;
f(argc, argv);
return 0;
}
推荐答案
Jefffrey 的评论 引用了标准,这里是:
Jefffrey's comment references the standard, here it is:
4.2 数组到指针的转换[conv.array]
4.2 Array-to-pointer conversion [conv.array]
可以转换类型为N T 数组"或T 未知边界数组"的左值或右值到指向 T 的指针"类型的纯右值.结果是一个指向数组的第一个元素.
An lvalue or rvalue of type "array of N T" or "array of unknown bound of T" can be converted to a prvalue of type "pointer to T". The result is a pointer to the first element of the array.
纯右值是:
纯右值(纯"右值)是标识临时值的表达式对象(或其子对象)或者是与任何不相关的值对象.
A prvalue ("pure" rvalue) is an expression that identifies a temporary object (or a subobject thereof) or is a value not associated with any object.
您不能将非常量引用绑定到临时引用.
You cannot bind a non-const reference to a temporary.
int& i = int(); // error
char* argv[] = { "", "", nullptr };
// the result of the conversion is a prvalue
char**& test = argv; // error
因此下面的代码会愉快地编译:
Therefore the following code will happily compile:
#include <iostream>
void f(int& argc, char** const& argv){
std::cout << argv[0] << std::endl; // a
}
int main()
{
int argc = 2;
char* argv[] = { "a", "b", nullptr };
f(argc, argv);
return 0;
}
在 OP 中提供的第一个示例中,char* argv[]
和 char** argv
是等效的.因此,没有转换.
In the first example provided in the OP, char* argv[]
and char** argv
are equivalent. Therefore, there is no conversion.
std::cout << std::is_array<decltype(argv)>::value << std::endl; // false
std::cout << std::is_array<char**>::value << std::endl; // false
std::cout << std::is_array<char*[]>::value << std::endl; // true
std::cout << std::is_same<decltype(argv), char**>::value << std::endl; // true
std::cout << std::is_same<decltype(argv), char*[]>::value << std::endl; // false
这篇关于C++ char*[] 到 char** 的转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!