我从命令行运行C ++ 11程序,如此,
marco @ host $ ./program.out a bb ccc
用于制作可执行文件的.cpp文件如下所示:
#include<iostream>
#include<vector>
#include<string>
int main(int argc, char* argv[]){
std::vector<std::string> strs = {argv + 1, argv + argc};
std::cout << strs[2] << endl;
return 0;
}
当我运行它时,它会输出 ccc 。由于列表初始值设定项仅包含两个类型为char *的元素,因此我没有预料到这一点。我之前看过这样的列表:
vector<string> strs = {"str1", "str2", ..., "strN"};
但指针初始化对我来说是全新的。似乎指针被视为开始和结束迭代器。 我的问题是,编译器如何知道从argv + 1迭代到argv + argc以初始化 strs 中的各个字符串?只是为了把事情放在上下文中,有没有办法在C中以类似的方式使用列表初始化来初始化char *数组?
答案 0 :(得分:6)
argv
是char *
的数组。如你所知,如果你不小心放牧,阵列就有这种腐烂的习惯。就这样:
{argv + 1, argv + argc}
这两个表达式都会产生char **
s。
您在想这里只是在进行普通的数组/向量初始化。你没有。这非常具有误导性,但这不是发生了什么。您显然无法使用std::string
s初始化char **
s,如果是您的花园种类列表初始化,则会出现这种情况。
这实际上是使用统一初始化语法进行解析的。在C ++ 11之前,这相当于:
std::vector<std::string> strs(argv + 1, argv + argc);
(仅用于说明目的,忽略了这里最令人烦恼的解析问题)。
你正在做的是使用它的构造函数构造一个向量,该构造函数的开头是一个序列的结束迭代器。 std::vector
有一堆构造函数。其中一个是一个模板,它接受一个序列的开始和结束迭代器,并将整个事物放入向量中。这就是你在这里做的事情。
这最终会使整个argv
填充向量(argv [0]除外)。这就是为什么你会看到你所看到的结果。