2017-06-19 88 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]除外)的向量填充。這就是爲什麼你看到你看到的結果。