2017-06-19 57 views
2

我是从像这样在命令行上运行的C++ 11方案,列表初始化向量<string>用2炭[]指针

马科@主机$ ./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 *类型的两个元素。我见过像这样的列表inits:

vector<string> strs = {"str1", "str2", ..., "strN"}; 

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

+1

“有没有一种方法可以在C中以类似的方式使用列表初始化来初始化char *数组?”会很好,不是吗?但是,它正在执行一个构造函数,它后面有很多C++ voodoo,它们不存在于C上。 – user4581301

回答

6

argvchar *的数组。正如你所知道的,如果你不小心放牧他们,阵列就有这种腐朽指向的习惯。因此:

{argv + 1, argv + argc} 

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

你以为你只是在这里做一个普通的数组/矢量初始化。你不是。这是非常具有误导性的,但这并非如此。您显然无法使用char ** s初始化std::string s,如果这是您的花园种类列表初始化,那么情况就是如此。

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

std::vector<std::string> strs(argv + 1, argv + argc); 

(仅用于说明的目的,忽略这里最棘手的分析问题)。

你在做什么是使用它的构造函数构造一个向量,该构造函数需要一个序列的结尾迭代器的开始。 std::vector有一堆构造函数。其中之一是一个模板,它将一个序列的开始和结束迭代器放入矢量中。这就是你在这里做的。

这真的会导致您的整个argv(argv [0]除外)的向量填充。这就是为什么你看到你看到的结果。