c++11 中引進了一種叫 list initializing 的技術,c++ primer 5th 的 3.3.1. defining and initializing vectors 中非常膚淺的介紹了一下它的形式:
書中頗為推崇這樣的初始化方式,且形式上更加貼近 c 語言中 array 的初始化過程,很是親民。cpp
vectorarticles = ; // or
vectorarticles;
但我們簡單做個實驗,來說明這種形式在效率上可能存在的問題:
猜猜看,這段程式的輸出是什麼?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 函式稍作修改:
然後檢視本次輸出:cpp
int 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 至容器中。
故:
相當於:cpp
std::vectorvec;
真相大白。cpp
std::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...