我从命令行像这样运行C++ 11程序,
marco @ host $ ./program.out一个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 *数组?
最佳答案
argv
是char *
的数组。如您所知,如果您不小心放牧数组,则数组就会习惯于衰减指针。因此:
{argv + 1, argv + argc}
这两个表达式都导致
char **
。您以为您在这里只是在进行普通的数组/ vector 初始化。你不是。这很容易引起误解,但事实并非如此。您显然无法使用
std::string
初始化char **
,如果是您的花园品种列表初始化,情况就是这样。实际上,这是使用统一的初始化语法进行解析的。在C++ 11之前,这等效于:
std::vector<std::string> strs(argv + 1, argv + argc);
(仅出于说明目的,在此忽略最烦人的解析问题)。
您正在执行的操作是使用其构造函数构造 vector ,该构造函数以序列的开始和结束迭代器为起点。
std::vector
有很多构造函数。其中一个是模板,它接受序列的开始和结束迭代器,并将整个对象放入 vector 中。那就是你在这里所做的。这实际上最终将 vector 与整个
argv
塞在一起(argv [0]除外)。这就是为什么您看到自己看到的结果。关于c++ - 用2个char []指针对vector <string>进行列表初始化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44621366/