列表初始化带有2个char []指针的向量<string>

Mar*_*rco 2 c++ pointers

我正在从命令行运行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;
}
Run Code Online (Sandbox Code Playgroud)

当我运行它时,它输出ccc.我没想到,因为列表初始化程序只包含char*类型的两个元素.我之前看过这样的列表内容:

vector<string> strs = {"str1", "str2", ..., "strN"};
Run Code Online (Sandbox Code Playgroud)

但指针init对我来说是全新的.似乎指针被视为开始和结束迭代器.我的问题是,编译器如何知道从argv + 1迭代到argv + argc来初始化strs中的各个字符串?只是为了把事情放在上下文中,有没有办法在C中以类似的方式使用列表初始化来初始化char*数组?

Sam*_*hik 6

argv是一个数组char *.如你所知,如果不小心地将它们放在一起,阵列就有这种腐烂的习惯.因此:

{argv + 1, argv + argc}
Run Code Online (Sandbox Code Playgroud)

这两个表达式都会导致char **s.

您在想这里只是在进行普通的数组/向量初始化.你不是.这是非常误导,但这不是正在发生的事情.你显然无法使用std::strings 初始化s,char **如果它是你的花园种类列表初始化就是这种情况.

这实际上是使用统一初始化语法进行解析的.在C++ 11之前,这相当于:

std::vector<std::string> strs(argv + 1, argv + argc);
Run Code Online (Sandbox Code Playgroud)

(仅用于说明目的,忽略了这里最令人烦恼的解析问题).

你正在做的是使用它的构造函数构造一个向量,该构造函数的开头是一个序列的结束迭代器.std::vector有一堆构造函数.其中一个是一个模板,它接受一个序列的开始和结束迭代器,并将整个事物放入向量中.这就是你在这里做的事情.

这实际上最终填充了整个向量argv(argv [0]除外).这就是为什么你会看到你所看到的结果.