慎用容器的 List Initializing

2021-09-20 04:24:47 字數 1557 閱讀 4800

c++11 中引進了一種叫 list initializing 的技術,c++ primer 5th 的 3.3.1. defining and initializing vectors 中非常膚淺的介紹了一下它的形式:

cppvectorarticles = ; // or

vectorarticles;

書中頗為推崇這樣的初始化方式,且形式上更加貼近 c 語言中 array 的初始化過程,很是親民。

但我們簡單做個實驗,來說明這種形式在效率上可能存在的問題:

cpp#include #include struct x 

x(const x&) // copy constructor

~x()

}int main()

;}

猜猜看,這段程式的輸出是什麼?

x()

x(const x&)

x(const x&)

x(const x&)

x(const x&)

~x()

~x()

~x()

~x()

~x()

看看有沒有猜對呢?

有沒有人好奇,為什麼 copy constructor 被呼叫了四次? 我們希望它被呼叫多少次呢?很顯然,是兩次。

我們對 main 函式稍作修改:

cppint main()

然後檢視本次輸出:

x()

x(const x&)

x(const x&)

~x()

~x()

~x()

第二次雖然多寫了幾行,但貌似極大程度上的避免了 copy constructor 的頻繁呼叫,想象一下若初始化列表裡躺著一大堆 x 會有什麼下場。

揭秘

copy constructor 的呼叫次數為何會翻倍?

因為 list initializing 本質上是先基於列表中的元素,構造出乙個initializer_list, 這個型別也是 c++11 引入的,可以看看詳細定義。

然後,再將構造出來的initializer_list中的元素逐一 copy 至容器中。

故:

cppstd::vectorvec;
相當於:

cppstd::initializer_listlist = ;  // copy 2 times

std::vectorvec(list); // copy 2 times

真相大白。

結論

對於非 built-in 物件來說, 使用 list initializing 付出的代價,在某些情況下不容忽視。

過去陳舊的寫法,反而讓人更加踏實。

慎用text indent的負值

文字文字 p這段 中我們希望隱藏文字,提公升 seo,所以使用 logo.png 這個進行替換,這時會對文字設定乙個負縮排值。這裡的 2500px 在以前基本可以解決隱藏文字的問題,但目前發現高解析度瀏覽器下這個值已經在瀏覽器可視範圍內了,造成文字隱藏失敗的問題。而如果將這個值設定為更大,如 999...

慎用text indent的負值

文字文字 p這段 中我們希望隱藏文字,提公升 seo,所以使用 logo.png 這個進行替換,這時會對文字設定乙個負縮排值。這裡的 2500px 在以前基本可以解決隱藏文字的問題,但目前發現高解析度瀏覽器下這個值已經在瀏覽器可視範圍內了,造成文字隱藏失敗的問題。而如果將這個值設定為更大,如 999...

慎用text indent的負值

文字文字 p這段 中我們希望隱藏文字,提公升 seo,所以使用 logo.png 這個進行替換,這時會對文字設定乙個負縮排值。這裡的 2500px 在以前基本可以解決隱藏文字的問題,但目前發現高解析度瀏覽器下這個值已經在瀏覽器可視範圍內了,造成文字隱藏失敗的問題。而如果將這個值設定為更大,如 999...