[洛穀日報第21期]你不知道的CPP11新語法

2020-12-16 洛谷科技

隨著C++11的發布,C++這門語言有了本質上的提升。C++14和C++17的相繼推出,更是讓C++這門語言達到了一個新高度。新的標準庫設施,新的語法,讓我們得以書寫更加安全、便捷、高效的程序。

2018年6月程式語言排行榜:

那麼這些新的語法究竟是什麼?它們如何使用?能為我們編程帶來哪些便利?這便是本文所探討的。

本文參考部分資料,文末已給出原文章地址。

新的空指針類型——nullptr

適用度:★★★★★

nullptr是一種特殊的字面值,它可以轉化為任意一種指針類型。原來我們初始化一個空指針都是直接將他賦值為NULL,但NULL實際上是一個宏,其值相當於0

編譯器是這麼定義NULL的:

也許你會想「我們用NULL還不是照樣吊打集訓隊」,nullptr好像並沒有什麼用。

考慮這樣一段代碼:

很顯然,編譯失敗,對f的調用有二義性。因為NULL相當於0,既可轉化為指針,也可轉化為整形。將NULL換做nullptr即可,nullptr便是為了解決這種二義性的問題而誕生的。

條件允許的前提下,儘量使用nullptr,它比NULL更加安全,原來這樣寫:

現在應該這樣寫:

避免奇葩錯誤——constexpr變量

適用度:★★★★☆

在編程中,我們經常遇到需要定義常量的情況,但有些常量卻並不是你所想的「常量」。因而會引發一些意想不到的錯誤。

例如:

i

b的確是一個常量——它的值在程序的執行期間不會被修改,但是它並不是常量表達式——每次執行程序時都為同一個值,且程序執行期間無法被修改。

使用constexpr而非const來聲明常量,讓編譯器來幫你檢查常量是不是每次程序執行都為同一個值。

省事好幫手——auto類型指示符

適用度:★★★★★

有些類型名字太長,難以拼寫,浪費時間。怎麼辦?

知道函數的作用,卻無法拼寫其返回類型,無法保存其返回值。怎麼辦?

這個時候auto類型指示符就能夠助我們一臂之力了。

原來我們這麼寫:

現在可以簡單的這麼寫:

怎麼樣?程序瞬間清爽了許多有木有。而且還可以節約大量寶貴的時間

因為編譯器是依靠初始值來推斷auto變量的類型的,所以auto變量必須要有初始值。

即使是這樣也不行:

當然,也不能用auto來定義數組

auto和引用一起會產生一些奇怪的問題:

為什麼?因為引用即別名。正如我們熟知的,使用引用其實是使用引用的對象,特別當引用被用作初始值的時候,真正參與初始化的其實是引用對象的值。此時編譯器以引用對象的類型作為auto的類型。

自動類型推斷——decltype類型指示符

適用度:★★★★☆

上文提到了auto的用法,有時候我們想要用表達式的類型初始化一個變量,卻並不想用表達式的值初始化這個變量。這個時候decltype類型指示符就可以派上用場了。

劇透:下文位置返回類型配合decltype類型指示符有驚喜

我們可以這樣用decltype類型指示符來定義變量:

但是要注意,decltype只會用表達式的返回值進行推斷,並不會執行表達式。例如:

decltype和auto都可以完成類型推斷的任務,那麼它們有什麼不同呢?

1.處理引用

2.處理頂層const

這裡引入一個概念:

1.底層const,對象所指向的對象是const的。2.頂層const,對象本身是const的。

auto會忽略掉頂層const和引用,但是會保留底層const。

如果要使auto類型為頂層const:

如果decltype使用的表達式是一個變量,decltype會返回該變量的類型(包括引用和頂層const)。

循環宏的優秀替代品——範圍for語句

適用度:★★★★★

什麼?就算有了auto類型指示符,遍歷容器/數組每一個元素你還是嫌麻煩?沒事,讓範圍for語句來幫你。

原來這麼遍歷容器/數組每一個元素

現在這麼寫:

注意,範圍for語句只能遍歷每一個元素,所以像遍歷1到10這種操作還是得自己乖乖寫for循環:)。

複雜返回值必備——尾置返回類型

適用度:★★★★☆

普通函數完全不必要尾置返回類型,但是當函數返回類型複雜起來時,尾置返回類型就很有用了。

很複雜,對吧?(當然對於dalao來說小菜一碟)當返回類型更加複雜時,常規寫法將會成為Debug噩夢。(話說Markdown好像識別不了尾置返回類型誒)。

還有更複雜的(我太蒻了給不出常規寫法了)

二維數組:

二重指針:

除了數組特殊一些以外,平時定義變量怎麼寫,尾置返回類型就怎麼寫。程序瞬間清爽了許多有木有。

如果返回值更加複雜,連尾置返回類型的作用都顯得微乎其微了怎麼辦?這時候——

配合decltype食用效果更佳

什麼?你連尾置返回類型都嫌麻煩?C++14可以滿足你的需求。沒錯,連尾置返回類型都可以省了,直接返回類型auto就可以了Orz。

命名困難戶/裝逼者的寵兒——Lambda表達式

適用度:★★★☆☆

假如遇到一道毒瘤題,既需要從小到大排序,也需要從大到小排序,甚至還要給自己定義的結構體排序。難道排序函數依次叫做cmp1,cmp2,cmp3?太沒有逼格了吧

一個完整的Lambda表達式由以下幾個部分構成:

各項具體含義如下

1.capture list:捕獲外部變量列表 可以為空,但是不可以省略

2.params list:形參列表 可以為空,但是不可以省略

3.mutable指示符:用來說用是否可以修改捕獲的變量 可以省略

4.exception:異常設定 可以省略

5.return type:返回類型 可以省略

6.function body:函數體 可以為空,但是不可以省略

太複雜了,對吧?實際上,OI中我們使用Lambda表達式主要是用於STL的謂詞(比如排序),因而我們可以省略很多不必要的部分。

該省略的省略後就十分簡單了:比如從大到小排序:

Lambda表達式看似複雜,卻能在許多時候為我們提供不小便利。它也是函數式編程的基石。

因考慮篇幅,Lambda表達式並未詳細介紹。想要知道更多關於Lambda表達式的內容,可以看看我的另一篇文章。傳送門

鳴謝:

本文參考了以下資料,感謝作者的辛勞付出:

https://www.jianshu.com/p/2d44dae53910

https://blog.csdn.net/zdy0_2004/article/details/69934828

https://www.cnblogs.com/DswCnblog/p/5629165.html

https://blog.csdn.net/y1196645376/article/details/51441503

注:因C++11語法繁雜,有些高級特性只為大型工程而設計,對OI並無太大幫助,因而未能出現在文章中(如繼承,多態,泛型編程)等等。本人水平有限,文章難免有錯誤,望讀者多多海涵,可以評論指出錯誤,一定盡力修正。

本文發布於洛穀日報,特約作者:colazcy

原文地址:https://www.luogu.org/blog/64456/ni-fou-zhi-dao-di-c-yu-fa

相關焦點

  • [洛穀日報第29期]OI中可以用到的Linux基礎教程
    Linux基礎教程●前置系統:任意Linux(不用NOI Linux也沒問題,我用的是deepin),如果沒有裝,而且你用的是win10,請看往期的洛穀日報:練習Linux?(3)NOI Linux不自帶的Geany、Code::Blocks等:因為不自帶,考試用不了,所以我也不做使用講解。文本編輯器無論你是用什麼編輯器(vim除外),我都建議你在目錄下新建一個cpp文件。
  • [洛穀日報第79期]二進位與位運算
    我也不知道「&」運算「&」運算,即「and」 運算,也是一種邏輯運算符,對於二進位運算來說,「&」運算的意義是對於兩個二進位數的每一位,如果這一位都是 1 ,那麼這一位為 1 ,否則這一位為 0 。
  • [洛穀日報第44期]強勢圖解AC自動機
    Q-讀者可能納悶了:你這裡的p一直在往字典樹後面走,沒有跳fail指針啊!這和KMP的思想不一樣啊,怎麼匹配得出來啊Answer to Q還記得剛才的字典圖嗎?事實上你並不是一直在往後跳,而是在圖上穿梭跳動。
  • [洛穀日報第46期]線段樹的擴展之淺談zkw線段樹
    0 閱讀本文前請先閱讀【洛穀日報#4】淺談線段樹(https://pks-loving.blog.luogu.org/senior-data-structure-qian-tan-xian-duan-shu-segment-tree)本文主要是上面文章的延伸,所以上文有講的東西本文就不詳細講了QwQ筆者的測試代碼可能寫醜了
  • [洛穀日報第35期]淺談自適應Simpson法
    差別不大,就認為區間 [a,b] 面積的近似值已經求得,否則分別對區間 [a,mid] 、區間 [mid,b] 遞歸應用本操作可以看出這個方法在保證了精度的同時保證了效率我們注意到,上述操作中有兩個地方含糊不清
  • [洛穀日報第38期]淺談如何在 Codeforces 下分
    另外,因抄襲代碼等原因造成的 Skip 同樣是不會被計入比賽的,被 Skip 的參賽選手狀態會變為 Out of Competition,並且比賽將不計入 rating。最重要的一點是,你必須屬於該場比賽要求的 rating 區間。
  • [洛穀日報第45期]談談關於初賽的那些事
    你甚至會發現,每年NOIP初賽的選擇題裡都會有一些神題,但也不缺乏送分題,比如下面這道就是典型的送分題:只要是個人的都知道選C好吧QAQ估計是CCF怕一些人爆零難看 普及組的選擇題其實不難,難的是提高組的不定項選擇題。這個比學校裡的考試要奇葩多了,CCF居然規定多選或少選均不給分。
  • [洛穀日報第53期]淺談一些求近似值的方法
    沒有問題,會用就行NOIP不考QwQ求零點、不動點、函數近似值、極值、最值……基本可以認為是一類問題,所以本文以討論如何** 求零點的近似值為主**因為筆者太弱所以沒有遺傳算法、模擬退火之類的玄學算法筆者是∑狂魔,要是有式子不理解請展開QwQ
  • [洛穀日報第22期]可以代替線段樹的樹狀數組?
    我們設a[1...i]的和為sum[i],根據delta數組的定義,則:這樣我們就不難看sum[i]是由哪三個部分組成的了。我們需要用一個asum數組維護a數組的前綴和,delta1與delta2兩個樹狀數組,delta1維護delta數組的和,delta2維護delta[i]*i的和,代碼如下:等等……線段樹不是還能查最大最小值嗎,事實上樹狀數組也能查。
  • [洛穀日報第19期]Codeforces遊玩攻略
    我們不詳細討論這個登錄完成後,我們看到網站變成了這樣:其實沒變多少側邊欄的內容依次為:即將舉行的比賽、用戶個人信息(注意若您沒有參加過計分的比賽,則不顯示Rating這一行)、比賽積分最高的前十個用戶等等。
  • [洛穀日報第59期]我有獨特的騙分技巧
    但暫且不談空間大小問題,單算算輸出時間複雜度就夠了。輸出 2e9 個數,再假設計算機運算速度為 1e9/s ,輸出速度為 2000B/s (很難做到),那最少也要輸出 1000000s ,約為11天,賽場上怎麼可能呢?所以還是要優化一些。
  • [洛穀日報第4期]淺談線段樹——Segment Tree
    ~~你看n^2的暴力幾乎什麼都可以維護~~二、逐步分析線段樹的構造實現1、建樹與維護那麼對於建樹,由於二叉樹自身的父子節點之間的可傳遞關係,所以可以考慮遞歸建樹(emmmm之前好像不小心劇透了qwq),並且在建樹的同時,我們應該維護父子節點的關係:2、接下來談區間修改
  • (2019-7-11) 問題與解答 (第16期)
    21.問:錄音答:在「全部消息」中先翻到5月31日,對照該日上傳的時間表上的日期,在「全部消息」中向前翻查,就可查到所有已經上傳的學習資料,包括課文朗讀錄音和音頻版講義。 22.問:入門級教材 入門級教學視頻入門級教學答:你是老師還是學生?
  • c++11-17 模板核心知識(零)—— 導語
    目錄為什麼要整理 cpp11-17TemplateTutorialC++ Templates (第 2 版 英文版)C++17 - The Complete
  • ​21年插本公共英語高頻語法檢測60期 — 高頻語法考點21【​特殊虛擬(should) do】
    0基礎、衝刺、大一大二、大三的插本考生學習建議:每日檢測一個語法點、每日學習1期(共60期)檢測學習內容:語法的考點是什麼?如何判斷語法考點?有哪些固定搭配、詞彙……插本公共英語QQ交流群高頻語法考點21真題:Our teacher suggested
  • 11.學習Python,刷題才能讓你感受到快(差)樂(距)!
    控制語句的語法雖然不多,但卻是程序的骨架,記住語法不難,真正理解並靈活應用卻不簡單。關於練習有朋友和我說,不是號稱初中生就能看懂嗎?我怎麼看不懂啊?我問他,是代碼執行失敗了,找不到原因嗎?也許把英語單詞和語法都背熟就能學好英語。但不做練習肯定學不好數學。學編程也是一樣!不寫代碼是不可能學會的!敲代碼的過程中有問題,可以留言或微信。
  • ​21年插本公共英語高頻語法檢測60期 — 高頻語法考點47【分數的表達】
    《專插本公共英語高頻語法考點檢測學習內容歸納》適用人群:英語語法
  • 有了這張寫作語法一覽圖,你就再也不犯糊塗!
    在平時上課和批改作業中,同學們經常犯各種語法錯誤,或者一句話總是寫不長,非常苦惱。其中的最主要原因就是語法體系不完善或者壓根沒怎麼學過語法,完全憑語感。這種情況是不能百分百應對所有的寫作的句型句式或者自己總也不知道自己哪裡有語法錯誤,就會失分或者提分不明顯。下面,根據大家的需求,梳理出寫作中需要掌握的語法點,幫助大家理清需要注意哪些語法錯誤和明白自己句子寫作的結構。有了這張寫作語法一覽圖,你就再也不犯糊塗!對於具體的語法知識點,大家可以微信提問~
  • ​21年插本公共英語高頻語法檢測60期 — 高頻語法考點50【so do I】
    0基礎、衝刺、大一大二、大三的插本考生學習建議:每日檢測一個語法點、每日學習1期(共60期)檢測學習內容:語法的考點是什麼?如何判斷語法考點?有哪些固定搭配、詞彙……高頻語法考點50真題:California relies heavily on income from fruit crops, _____.
  • ​21年插本公共英語高頻語法檢測60期 — 高頻語法考點16【比較級的倍數】
    0基礎、衝刺、大一大二、大三的插本考生學習建議:每日檢測一個語法點、每日學習1期(共60期)檢測學習內容:語法的考點是什麼?如何判斷語法考點?翻譯:Tim將和他的朋友們去看那部新電影。檢測:A library with five thousand books _____ to the nation as a gift.