我从命令行像这样运行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 *数组?

最佳答案

argvchar *的数组。如您所知,如果您不小心放牧数组,则数组就会习惯于衰减指针。因此:

{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/

10-16 18:03