C/C++tips3(c++11及以后)

吐槽一下笔链,經(jīng)典的c++98經(jīng)過c++11和c++14的升級后段只,似乎一下變成了另一種編程語言了。c++11和c++14引入了大量的新特性鉴扫,使我感覺c++的復雜程度一下上升了數(shù)倍赞枕。
這里的很多主題都非常復雜,我僅僅把我自己的理解大致記錄下來,具體內(nèi)容還是要去看看c++主題演講

cv-qualified

在一些資料中經(jīng)晨簧簦看到cv-qualified type之類的詞語谍椅,這里的cv就是const & volatile,即不變和易變修飾符古话,cv-qualified type就是以const或者volatile修飾的類型雏吭。
在使用模版函數(shù)或者auto時,根據(jù)參數(shù)的類型陪踩,編譯器的類型推導會自動地推導出cv-qualified type杖们。
例如:

// 1\. 模版函數(shù)

template<typename T>
void func(T& t) {…}
const int a = 1;
func(a);    // 模版函數(shù)參數(shù)的類型成為const int&

// 2\. auto
const int a = 3;
auto& var = a;    // var的類型成為const int&

但是,如果模版函數(shù)或者auto不是引用或者指針肩狂,那么得到的類型是去除了cv-qualified的類型摘完。因為此時新的標識符有了獨立的內(nèi)存空間,對于原標識符內(nèi)存空間的修飾當然不應該繼續(xù)生效了傻谁。

左值和右值

C++規(guī)定:凡是能夠通過取地址運算符取得變量在內(nèi)存中地址的孝治,就是左值,否則就是右值审磁√胳可以這樣理解:左值是存在于內(nèi)存中的變量(不論是堆內(nèi)存還是棧內(nèi)存),而右值是僅存在于寄存器中的臨時變量态蒂。

decltype

decltype可以推斷一個標識符的類型杭措,這個類型是編譯時推導出的。
由于lambda表達式的類型是無名的钾恢,因此如果想要獲得lambda表達式的類型手素,只能使用decltype(lambdaExpr)。例如:

auto f = [](int a, int b) -> int
{
    return a * b;
};

decltype(f) g = f; // lambda 的類型是獨有且無名的
i = f(2, 2);
j = g(3, 3);

using和typedef

在C++11中瘩蚪,鼓勵使用using來替代原來的typedef定義類型別名泉懦。using強制將類型名稱放到等號左邊,而將類型放到等號右邊疹瘦,提高了可讀性崩哩;此外,using還支持泛型拱礁,而typedef不支持泛型琢锋。
舉一個例子:

typedef int (*myFunc)(int, char*);
using myFunc = int (*)(int, char*);

類型推斷(type deduction)

scott mayer的演講闡明了一些非常容易被忽視或者混淆的基本概念,理解這些基礎是理解C++11和C++14新增內(nèi)容的必要知識呢灶。
https://www.youtube.com/watch?v=wQxj20X-tIU

右值引用 & 移動語義

右值引用和移動語義也是在C++11新增的詞吴超,用于解決對象在右值賦值時會不必要地進行額外操作的問題。此外鸯乃,同樣利用C++0x引用的T&&右值引用這種寫法鲸阻,也可以實現(xiàn)所謂的“通用引用Universal Reference”跋涣,從而實現(xiàn)完美轉(zhuǎn)發(fā)。
C++從一開始就規(guī)定了引用的語義鸟悴,不過卻沒有提到“左值”或者“右值”引用陈辱,事實上,左值引用正是我們一直以來在C++中使用的引用细诸,過去的C++標準沒有規(guī)定右值引用沛贪,因此過去一直無法使用右值引用。C++0x中規(guī)定:右值引用能夠通過兩個引用符號表示震贵,如果一個函數(shù)的參數(shù)類型是T&&利赋,那么這個函數(shù)就會匹配右值引用參數(shù)。使用右值引用時猩系,我們可以確定右值引用對象在函數(shù)被調(diào)用完成后就會被丟棄媚送,因此可以直接將右值引用對象資源“移動”到this對象中而不用擔心這樣做會導致右值引用對象的狀態(tài)遭到破壞(因為之后這個對象就用不到了,會被立即銷毀)寇甸。
如上所述塘偎,使用右值引用時,能夠確保右值引用對象會在隨后被銷毀拿霉,因此可以將右值引用對象的資源直接“移動”到當前對象中吟秩,“移動”就是指將資源淺拷貝到當前對象,然后將右值引用對象中的資源引用置空友浸。這樣峰尝,原本由右值引用持有的資源就移動到了當前對象中。這就是移動語義收恢。
C++0x同時在標準庫中新增了std::move,move將參數(shù)轉(zhuǎn)為右值引用并返回祭往,而forward根據(jù)參數(shù)是左值還是右值返回對應的引用伦意。

通用引用 & 完美轉(zhuǎn)發(fā)

通用引用其實就是右值引用,但是scott mayer認為右值引用不準確硼补,因為有時候“右值引用”引用的其實不是一個右值驮肉,因此他堅持使用“通用引用”而不是“右值引用”。
以下列舉通用引用的例子:

// 1\. T由編譯器進行類型推倒
template <typename T>
void function(T&& t);

// 2\. 使用auto已骇,auto的推導規(guī)則其實和范型方法一樣离钝,因此也可以被歸為上面一類
auto&& t;

完美轉(zhuǎn)發(fā)(perfect forwarding)問題是指函數(shù)模板在向其他函數(shù)傳遞參數(shù)時該如何保留該參數(shù)的左右值屬性的問題。
也就是說函數(shù)模板在向其他函數(shù)傳遞自身形參時褪储,如果相應實參是左值卵渴,它就應該被轉(zhuǎn)發(fā)為左值;同樣如果相應實參是右值鲤竹,它就應該被轉(zhuǎn)發(fā)為右值浪读。
這樣做是為了讓其他函數(shù)能夠針對轉(zhuǎn)發(fā)而來的參數(shù)的左右值屬性進行不同處理。
參考上面提到的通用引用的例子1,此時不論T&&被推導為左值引用還是右值引用碘橘,實際上的t都會變成左值引用互订,因為在函數(shù)內(nèi)的參數(shù)引用有了名字,能夠被引用了痘拆,從而不符合右值的定義仰禽。但是,編譯器會記住t實際上是個右值纺蛆,如果希望獲取t原本的引用類型坟瓢,就需要使用新增的std::forward方法來獲取引用的實際類型。

lambda

auto

auto是自動類型推導犹撒,可以根據(jù)表達式的返回自動推導出變量的類型折联。可以使用const & volatile以及引用&指針來修飾auto類型標識识颊。

std::initializer_list

c++11標準庫中新增了一個重要的類型定義:

template< class T >
class initializer_list;

一個initializer_list<T>是一個輕量級的代理對象诚镰,可以通過它訪問一組類型為T的數(shù)組。
在以下情況下祥款,initializer_list會被自動創(chuàng)建:

// class MyClass有一個接受std::initializer_list的構造函數(shù)
MyClass a({1, 2, 3});
MyClass a = {1, 2, 3};
for (auto& a : {1, 2, 3}) {...}
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末清笨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子刃跛,更是在濱河造成了極大的恐慌抠艾,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件桨昙,死亡現(xiàn)場離奇詭異检号,居然都是意外死亡,警方通過查閱死者的電腦和手機蛙酪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門齐苛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人桂塞,你說我怎么就攤上這事凹蜂。” “怎么了阁危?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵玛痊,是天一觀的道長。 經(jīng)常有香客問我狂打,道長擂煞,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任菱父,我火速辦了婚禮颈娜,結果婚禮上剑逃,老公的妹妹穿的比我還像新娘。我一直安慰自己官辽,他們只是感情好蛹磺,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著同仆,像睡著了一般萤捆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上俗批,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天俗或,我揣著相機與錄音,去河邊找鬼岁忘。 笑死辛慰,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的干像。 我是一名探鬼主播帅腌,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼麻汰!你這毒婦竟也來了速客?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤五鲫,失蹤者是張志新(化名)和其女友劉穎溺职,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體位喂,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡浪耘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了忆某。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片点待。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖弃舒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情状原,我是刑警寧澤聋呢,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站颠区,受9級特大地震影響削锰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜毕莱,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一器贩、第九天 我趴在偏房一處隱蔽的房頂上張望颅夺。 院中可真熱鬧,春花似錦蛹稍、人聲如沸吧黄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拗慨。三九已至,卻和暖如春奉芦,著一層夾襖步出監(jiān)牢的瞬間赵抢,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工声功, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留烦却,地道東北人。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓先巴,卻偏偏與公主長得像其爵,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子筹裕,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容