我正在阅读《C++ Primer》,在第6.2节中,书中写道:
“参数初始化的方式和变量初始化一样。”
然而,当我这样做时:
void foo(char* args[]) {return;}
int main() {
char* args[]={"asd","dsa"}; // ok.
foo({"asd","dsa"}); // error.
}
为什么会这样呢?
正如评论中@T.C.所指出的那样,函数参数中的args被转换为char **,因为函数无法将数组作为参数传递。由于你不能这样做:
char **asd={"asd","dsa"};
代码是非法的。我的困惑来自于这一事实。
char* args[]={"asd","dsa"};
char **asd=args;
通常可以利用新的初始化语法和语义来使用匿名数组作为参数,但需要跨越一些障碍。例如:
typedef const char *CC2[2];
void foo(const CC2 &a) {}
int main() {
foo({ "asd", "dsa" });
}
然而,在您的情况下,该技术将无法帮助您,因为您正在请求对临时数组进行数组到指针的转换。在C++中,这是非法的。
typedef int A[2];
const A &r = A{ 1, 2 }; // reference binding is OK
int *p = A{ 1, 2 }; // ERROR: taking address is not OK
template <size_t N> void foo(const char *const (&args)[N]) {}
int main() {
foo({ "asd", "dsa" });
}
为什么呢?
首先,在这两种情况下,你需要使用 char const*
,因为你正在使用字符串字面量。
其次,如果参数类型是数组,则 {...}
可以工作,但是 char*[]
会被 调整 为 char**
(由于衰减),无法用 大括号初始化列表 进行初始化。
或者使用 std::string
和 std::vector
,因为你已经应该这样做了:
void foo(std::vector<std::string> args) {return;}
并且:
foo({"asd","dsa"});
{...}
在初始化非类类型(且不是从 auto
推导)时,从未被推导为 std::initializer_list
。而且,参数类型也不是 T[]
。声明会被调整为 T*
,如果参数是数组,则会隐式转换。 - David G
args
的类型不是一个数组。 - T.C.