標籤:

為什麼判斷 std::vector 是否為空時,用 if(0==vec.size()) 提示效率低,但用 if (vec.empty()) 正常?

編譯器錯誤:Possible inefficient checking for "vecAttrValue" emptiness


這要看編譯器的具體實現。以下就gcc為例:

對於std::vector來說, 其實效率沒區別. 但對於std::list來說(gcc 4.6-), empty()的效率是O(1), size()的效率是O(n). 所以更好的習慣, 應該是在這種情況下, 統一使用empty().

C++11對size()的效率做了一致性的規定。所以在gcc 4.7+, std::list的複雜度也是O(1)了。原因是增加了一個「size」的變數來存長度。

參考:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49561


可能原因是你用的 cppcheck 版本 ≤1.58。

1.58 版本對任何 STL 容器的 size() == 0 都報這個。

1.59 版本則只對確實低效(比如 std::list)報這個。

Fixed #2652 (container .size() check too strict) · 08ada4c · danmar/cppcheck · GitHub


問你火車來了沒來,你瞄一眼就夠了;

問你火車來了幾節車廂,你得看仔細了,車頭的GPS坐標,車尾的GPS坐標,差值再除以車廂長度。


《effective stl》里第4條就已經解釋了,建議你去看看


用empty 而不是用size 判斷是個好習慣,因為並不是所有容器,所有廠商實現STL的size 是O(0),而empty一定是。


size()是end()-begin().

empty()是判斷begin()==end().


《effective stl》第四條

調用empty而不是檢查size()是否為0

empty對所有的標準容器都是常數時間操作,而對一些list實現,size耗費線性時間。

原因是list獨有的鏈接操作(splice),代碼如下:

list& list1;
list& list2;
...
list1.splice(list1.end(), list2, find(list2.begin(), list2.end(), 5),
find(list2.rbegin(), list2.rend(), 10).base());

鏈接到list1的元素個數是兩個find之間的數量,但是無法知道具體有多少個。而標準容器中,list具有把元素從一處鏈接到另一處而不需要拷貝任何數據。因此從一個list鏈接到另一個list可以通過常數時間完成。因此容器的設計者需要決定到底是size還是其他相關操作(例如splice)哪個是常數時間。

//PS:有人知道問什麼現在網上都沒有effective stl賣了?各家電商都說是缺貨,我這本還是從圖書館借的。


性能沒區別。

提示信息都寫了, "Possible"。這種靜態檢查是不可能完全對的。


推薦閱讀:

C/C++中char/int/long等基本內置類型為何要編譯器相關而不是固定長度?
Visual C++.NET的存在意義是什麼?
如何評價 JetBrains 的新 C/C++ IDE CLion?
為什麼不能在 std::map 中使用局部類型?
C++ unordered_map 中 double 作key如何在模板參數中實現?

TAG:STL | C |