本篇介紹幾個(gè)細(xì)瑣的小特性,可以使代碼更加安全可靠。
最常見的情況是采取 for loop 遍歷某個(gè)容器,比如:
std::vectorv(10); std::iota(v,0); for(inti=v.size()-1;i>=0;--i){ std::cout< 乍看之下,似乎并無問題,但實(shí)際上卻存在安全隱患,若是 v.size() 的結(jié)果大于 std::numeric_limits
::max(),將產(chǎn)生 UB。 倘若你使用了類型推導(dǎo),問題會(huì)更加明顯。
for(autoi=v.size()-1;i>=0;--i){ std::cout<這會(huì)輸出超出預(yù)期的結(jié)果!i 被推導(dǎo)為 unsigned 整型,i >= 0 將永遠(yuǎn)為真。
這種隱患來自于類型的隱式轉(zhuǎn)換,一般編譯器只會(huì)給出警告。最簡(jiǎn)單的解決之法就是保證整型符號(hào)的一致性,例如:
for(size_ti=v.size()-1;i結(jié)束條件也隨之變?yōu)?a target="_blank">檢測(cè)數(shù)據(jù)范圍,以避免條件在邏輯上的無效性。但如此一來,可讀性直線降低,C++20 引入了幾個(gè)與此相關(guān)的小特性,可以更安全地解決該問題。
第一個(gè)是一系列整型比較函數(shù),它們可以安全地對(duì)不同符號(hào)的類型進(jìn)行比較。如:
-1>0u;//true std::cmp_greater(-1,0u);//false因此,可以用來安全地比較不同符號(hào)的整型。
for(inti=0;std::cmp_less(i,v.size());++i){ std::cout<通過使用這些安全的比較函數(shù),代碼隱患隨之消除。只是無法逆序遍歷了,逆序時(shí)將 size_t 賦值到 int 依舊有可能產(chǎn)生 UB。
此種情境,更好的方式是采用 std::ssize(),它是一個(gè)有符號(hào)的 size() 輔助函數(shù),表意更加直接。代碼更改為:
for(inti=ssize(v)-1;i>=0;--i){ std::cout<得益于 ADL,std::ssize() 可以簡(jiǎn)寫為 ssize()。
當(dāng)然,以上只是示例需要,對(duì)于數(shù)據(jù)遍歷,Range-based for loop 是更好的方式,這樣能夠避免很多易被忽視的錯(cuò)誤。
for(constauto&elem:v){ std::cout<通過 C++20 Views,還可以在遍歷時(shí)組合其他操作,如:
for(constauto&elem:v|std::reverse){ std::cout<
這是可讀性最強(qiáng)的方式。
當(dāng)然,還有許多其他方法,比如迭代器、算法和一些技巧,但在范式上來說,那些方法很難比這里展示的方式更加簡(jiǎn)潔,就使用來說,記住這里提到的便已足夠。
推薦閱讀點(diǎn)擊標(biāo)題可跳轉(zhuǎn)
1、深入淺出 C++ 類型擦除
2、性能大殺器:c++中的copy elision
3、Configuring Transitive Dependencies with Modern CMake
-
函數(shù)
+關(guān)注
關(guān)注
3文章
4346瀏覽量
62968 -
C++
+關(guān)注
關(guān)注
22文章
2114瀏覽量
73854
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論