不知道C++這七大特性,絕對枉爲圈中人

做爲一種計算機語言,C++經歷了許多發展變化。程序員

固然,這些改變並非一蹴而就的。C++曾經缺少活力與創新,所以很不受歡迎。編程

可是在C++標準委員會決定加速發展這個語言以後,形勢發生了改變。小程序

2011年起,C++一躍成爲了具備活力、不斷演進、廣受喜好的計算機語言。
最後,若是你們若是在自學遇到困難,想找一個C++的學習環境,能夠加入咱們的C++學習圈,點擊我加入吧,會節約不少時間,減小不少在學習中遇到的難題。安全

圖片描述
C++蛻變後也並無簡單多少,還是最難的編程語言之一。可是,C++確實比以前更加人性化了。數據結構

本文要講的是的C++的一些新特性(以有8年曆史的C++11爲例),相信每一個程序員都會對這個話題感興趣。編程語言

注:本文略過了一些高級特性。ide

  1. 關鍵字auto

當C++11第一次引入auto時,程序員們紛紛喜極而泣!函數

auto的意義是使C++編譯器能夠在編譯時推導數據類型,這樣就不用每次都要聲明數據類型了。當數據類型爲map<string,vector<pair<int,int>>>時尤其便捷。學習

不知道C++這七大特性,絕對枉爲圈中人this

沒有initializer,就沒法聲明數據類型(見第五行)。這是說得通的。第五行指令並無讓編譯器推導數據類型。

起初,auto的功能比較有限。在以後新版本的C++中,auto的功能愈來愈強大。

不知道C++這七大特性,絕對枉爲圈中人

第七行和第八行中使用了括號初始化 (bracketedinitialization),這也是C++11的新特性之一。

請注意使用auto時,編譯器必須可以推導數據類型。

一個有趣的問題是:若是寫下autoa = {1, 2, 3}會發生什麼?這是個編譯錯誤嗎?是一個矢量嗎?

不知道C++這七大特性,絕對枉爲圈中人

實際上,C++11引入了std::initializer_list<type>.若是聲明auto,花括號初始化列表會被當作輕量級容器。

最終,正如前文所言,當數據結構複雜時,編譯器類型推導頗有幫助:

不知道C++這七大特性,絕對枉爲圈中人

別忘了檢查第25行!auto [v1,v2] = itr.second純粹是C++17的新特性。這個特性叫作結構化綁定。在舊版本C++中,程序員須要單獨獲取每一個變量。可是結構化綁定給這一過程帶來了便利。此外,若是想得到數據使用引用(reference),只須要加上一個symbol--auto&[v1,v2] = itr.second.

  1. Lambda表達式

C++11引入了lambda表達式,這相似於JavaScript裏的匿名函數。它們都是函數對象,沒有名字,且基於簡潔的語法在不一樣做用域上捕獲變量。它們也能夠被分配給變量。

若是須要在代碼中進行一些小而快的操做,又不肯意爲此單獨寫一個函數,那麼Lambdas頗有用。另外一種常見用法是將lambdas做爲比較函數。

不知道C++這七大特性,絕對枉爲圈中人

以上例子能夠說明不少問題。

首先,請注意花括號初始化是如何提高權重的。而後是通用的begin(),end() (這也是C++11的新增部分)。接着是做爲數據比較器的lambda函數。lambda函數的參數被聲明爲auto(這是C++14的新增部分)。在C++14以前是不能對於函數參數使用auto 的。

正如現代C++的awesome庫中定義的那樣:

· []—不捕獲任何對象。因此不能在lambda表達式內使用全局做用域的局部變量,只能使用參數。

· [=]— 按值捕獲做用域中的局部對象(局部變量,參數)。只可以使用不可修改。

· [&]—按引用捕獲做用域中的局部對象(局部變量,參數)。能夠被修改。例子以下。

· [this]—按值捕獲this 指針。

· [a, &b]—按值捕獲對象a ,按引用捕獲對象b。

因此,若是想在lambda函數內部將數據轉換爲其餘格式,能夠利用做用域的優點來運用lambda.好比:

不知道C++這七大特性,絕對枉爲圈中人

在上面這個例子中,若是在lambda表達式中按值捕獲([factor])局部變量,則不能改變第五行的factor.緣由很簡單——沒有權限。

最終,請注意示例中使用了val 做爲引用 (reference). 這確保了lambda函數內部的任何變化都會改變vector.

不知道C++這七大特性,絕對枉爲圈中人

學完現代C++後,她們樂開了花!(攝影:Ian Schneider 圖源:Unsplash)

  1. if/switch內的初始化語句

C++17的這個特性十分討喜:

不知道C++這七大特性,絕對枉爲圈中人

很明顯,如今能夠同時在if/switch句塊內進行變量初始化和條件檢查。這有助於保持代碼簡潔精煉。通用形式爲:

if( init-statement(x);condition(x)) {
// do some stuff here
} else {
// else has the scope of x
// do some other stuff
}

  1. 在編譯時使用constexpr

constexpr 很棒!假如要評估一些表達式,且它的值一旦初始化就不會改變,那麼能夠預運算其值並將之做爲宏。或者利用C++11提供的constexpr.

程序員傾向於儘可能減小程序運行時間。因此,若是能讓編譯器進行一些操做並減少程序運行的壓力,那麼就能夠縮短運行時間。

不知道C++這七大特性,絕對枉爲圈中人

以上代碼是constexpr的常見例子之一。既然聲明斐波那契數列函數爲constexpr, 那麼編譯器就能夠在編譯時預運算fib(20). 因此編譯以後,能夠用constlong long bigval = 2432902008176640000來替代const longlong bigval = fib(20).

請注意,傳遞參數是一個const 值。這是被聲明爲constexpr的函數的一個重點——傳遞參數應該是constexpr或const。不然這裏的函數會和普通函數同樣,也就是說編譯時不進行預運算。

變量也能夠是constexpr. 在這種狀況下,這些變量在編譯時必須可評估;不然會出現編譯錯誤。

有趣的是,後來在C++17中引入了constexpr-if 和constexpr-lambda.

  1. Tuples元組

與pair很是相似, tuple是各類數據類型的固定大小值的集合。

不知道C++這七大特性,絕對枉爲圈中人

有時,相比於tuple,使用 std::array更方便。array相似於帶有C++標準庫的功能的plain C陣列。這個數據結構是C++11新增的。

  1. 類模板參數推導

這個特性的名字還挺囉嗦。從C++17開始,標準類模板也能夠進行模板參數推導。以前,模板參數推導只支持函數模板。結果就是:

std::pair<std::string,int> user = {"M", 25}; // previous
std::pair user = {"M", 25}; // C++17

這種推導是「隱性的」。這對於tuple來講就更方便了。

// previous
std::tuple<std::string, std::string, int> user ("M","Chy", 25);
// deduction in action!
std::tuple user2("M", "Chy", 25);

以上這一特性對不熟悉C++模板的人來講沒有太大用處。

  1. 智能指針

指針有時很恐怖。因爲C++語言爲程序員提供了很大程度的自由,因此有時很容易搬起石頭砸本身的腳。並且不少狀況下,麻煩是由指針形成的。

幸運的是,C++11引入了智能指針,智能指針比普通指針便捷得多。它們經過適時釋放內存來幫助程序員防止內存泄漏。它們還有助於代碼達到異常安全等級。

C++爲最新版本的計算機語言引入了許多全新的特性。若是你感興趣,能夠進行深刻了解。

不知道C++這七大特性,絕對枉爲圈中人

相關文章
相關標籤/搜索