需要可變參數(shù)的時候冲粤,為什么不用vector代替initializer_list袜茧?

在重載的時候摧冀,vector會有問題倍踪。

當需要可變參數(shù),如果使用vector的話索昂,可能會遇到下面這個問題建车。函數(shù)f有兩個重載的版本,編譯器無法選擇具體調(diào)用vector還是list的版本椒惨。

void f(std::vector<int> const &items){};
void f(std::list<int> const &items){};

f({ 1, 2, 3, 4 }); //ambiguous call to overloaded function

而使用initializer_list的話缤至,就不會出現(xiàn)錯誤了。編譯器優(yōu)先匹配了initializer_list的版本康谆。

void g(std::vector<int> const &items){};
void g(std::list<int> const &items){};
void g(std::initializer_list<int> const &items){};

g({ 1, 2, 3, 4 });  // no error

initializer_list不能修改领斥,更符合參數(shù)的特點。

vector有push_back函數(shù)沃暗,也就是說vector可以在函數(shù)里面修改月洛,所以必然vector必須在heap上分配空間來存儲數(shù)據(jù)。
initializer_list只有beginend函數(shù)描睦,函數(shù)內(nèi)并不能修改它膊存,所以編譯器有機會在stack上存儲initializer_list的數(shù)據(jù)來提高性能导而。

initializer_list has pointer semantics while the vector has value semantics.

vector語義忱叭,也就是說拷貝一個vector隔崎,那里面的元素也會被拷貝一次。而initializer_list指針語義韵丑,里面的元素并不會被拷貝爵卒。比如說下面這段代碼listlist2begin其實指向了同一個空間。這樣的設計是合理的撵彻,因為initializer_list是不可修改的钓株,沒有理由再拷貝一次。

    std::initializer_list<int> list = { 1, 2, 3, 4 };
    std::initializer_list<int> list2;
    list2 = list;
    std::cout << list2.begin() << std::endl;
    std::cout << list.begin() << std::endl;

指針語義的好處是陌僵,下面這段遞歸函數(shù)不會對里面的元素產(chǎn)生很多次復制轴合。雖然每次都構(gòu)造了一個新的initializer_list,但是里面的數(shù)值{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }并沒有經(jīng)過復制碗短。

int sum(std::initializer_list<int> const &items)
{
    std::cout << items.begin() << std::endl;
    if (items.begin() == items.end()){
        return 0;
    }
    std::initializer_list<int> next(items.begin() + 1, items.end());
    return  *(items.begin()) + sum(next);
};

std::cout << sum({ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });

initializer_list 背后的設計思想受葛。

在C++11的時候,大家都想加上一個值列表的東西偎谁,就像{ value1, value2, value2... valueN }一樣总滩。一種想法是搞出一個新的關(guān)鍵字,給C++增加一個新的build-in類型巡雨。但是新的關(guān)鍵字很有可能會導致老的程序無法被編譯闰渔,如果湊巧老的程序使用了那個關(guān)鍵字做名字。
于是C++11的做法是铐望,只是在標準模板庫里面增加一個新的模板initializer_list冈涧,然后讓編譯器遇到{1,2,3,4}這種東西的時候,隱式的轉(zhuǎn)換成一個initializer_list的對象正蛙。下面這段代碼輸出的是class std::initializer_list<int>

    auto list = { 1, 2, 3 };
    std::cout << typeid(decltype(list)).name() << std::endl;    

有了這個基本的東西以后炕舵,剩下的問題就可以在已有的框架里面解決了。比如說實現(xiàn)std::vector<int> v = { 1, 2, 3 };這個功能跟畅。其實就是編譯器遇到{ 1, 2, 3 }就生成了一個initializer_list咽筋,然后調(diào)用了vector對應的一個構(gòu)造函數(shù).

vector( std::initializer_list<T> init, const Allocator& alloc = Allocator() );

回到最初的fg的例子,g({ 1, 2, 3, 4 });沒有編譯錯誤徊件,因為有一個最佳的匹配奸攻。
f({ 1, 2, 3, 4 });出現(xiàn)了編譯錯誤,因為沒有最佳的一個匹配虱痕,編譯器面臨著隱式類型轉(zhuǎn)換睹耐,但是有兩個選擇,vector和list部翘,所以就有編譯錯誤了硝训。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子窖梁,更是在濱河造成了極大的恐慌赘风,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纵刘,死亡現(xiàn)場離奇詭異邀窃,居然都是意外死亡,警方通過查閱死者的電腦和手機假哎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門瞬捕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人舵抹,你說我怎么就攤上這事肪虎。” “怎么了惧蛹?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵笋轨,是天一觀的道長。 經(jīng)常有香客問我赊淑,道長爵政,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任陶缺,我火速辦了婚禮钾挟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘饱岸。我一直安慰自己掺出,他們只是感情好,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布苫费。 她就那樣靜靜地躺著汤锨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪百框。 梳的紋絲不亂的頭發(fā)上闲礼,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天,我揣著相機與錄音铐维,去河邊找鬼柬泽。 笑死,一個胖子當著我的面吹牛嫁蛇,可吹牛的內(nèi)容都是我干的锨并。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼睬棚,長吁一口氣:“原來是場噩夢啊……” “哼第煮!你這毒婦竟也來了解幼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤包警,失蹤者是張志新(化名)和其女友劉穎撵摆,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體揽趾,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡台汇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年苛骨,在試婚紗的時候發(fā)現(xiàn)自己被綠了篱瞎。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡痒芝,死狀恐怖俐筋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情严衬,我是刑警寧澤澄者,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站请琳,受9級特大地震影響粱挡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜俄精,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一询筏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧竖慧,春花似錦嫌套、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至砍的,卻和暖如春痹筛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背廓鞠。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工味混, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人诫惭。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓翁锡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親夕土。 傳聞我的和親對象是個殘疾皇子馆衔,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容