C++11類型系統(tǒng)

C++ feels like a new language. -- Bjarne Stroustrup

  1. 類型推演
  2. 右值引用
  3. 通用引用
  4. 剖析std::move
  5. 剖析std::forward
  6. 總結

類型推演

增強了的「類型系統(tǒng)」是C++11最大的優(yōu)化亮點之一,為此需要深入剖析「類型推演」的工作機理,并能靈活地運用auto, decltype,這是C++11最重要的基石。

template與auto

C++98早已具備類型推演的能力苔巨,用于模板的類型推演。

C++11中,autotemplate的類型推演能力基本類似魏割,只存在唯一的差異:Braced Initialization,或稱為Universal Initialization耙蔑。

非常量的左值引用

需要注意的是见妒,推演auto &r2 = r, auto &cr2 = cr時,即使r(int&), cr(const int&)是引用變量甸陌,需要去除引用后再嘗試類型推演须揣,因為使用「引用變量」等價于使用其「引用對象」本身。

常量的左值引用

因為const T&钱豁,const auto&已經(jīng)具備了const的屬性耻卡,當const的左值對象賦予它所發(fā)生的自動類型推演,其模板參數(shù)T牲尺,及其auto的類型無需推演為const屬性卵酪。


指向非常量的指針

指針的推演能力與引用類似。

需要注意auto *p = &i; auto p = &i兩種寫法的不一樣谤碳,一種是顯式的指針類型溃卡,另外一種完全依賴于auto的類型推演能力。

指向常量的指針

與指向非常量的指針推演機制一致蜒简,在此不再冗述瘸羡。


按值傳遞

Pass-By-Value,經(jīng)過拷貝之后搓茬,兩者之間已無任何瓜葛犹赖,為此const的處理機制有別于其他情況队他。



但存在兩類特殊的,遺留的C-Style情況峻村,為保證兼容性麸折,存在特殊的類型推演機制。

遺留的C-style字符串

遺留的C-style函數(shù)

通用引用:Universal Reference

所謂Universal Reference粘昨,因為其能Can bind to anything垢啼,所以稱為「通用引用」,具有如下方面的特點:

  • Can bind to lvalue or rvalue;
  • Can bind to const/non-const, volatile/non-volatile, or both;
  • So, it can bind to anything.

需要注意的是张肾,Universal Reference并非「右值引用(Rvalue Reference)」膊夹,即使它們兩者都有類似的T &&的修飾符。規(guī)則非常簡單捌浩,Universal Reference具備兩個最基本的特征:

  • T &&, auto&&: 必須具備的句法結構
  • type reduce:必須發(fā)生類型推演

可以簡單歸納之放刨,Universal Reference出現(xiàn)于如下兩種常見:

template <typename T>
void f(T&& t);

auto&& r = i;

Universal Reference類型推演也存在特殊性:

  • Universal Reference持有左值時,發(fā)生Reference Collapsing機制尸饺。例如auto&& t = i进统,當auto推演為int&auto&& t推演為int& && t浪听,而int& &&經(jīng)過Reference Collapsing機制螟碎,被進一步規(guī)約為int&,與原來它持有左值剛好匹配迹栓。

  • Universal Reference持有右值時掉分,推演規(guī)則較為直觀,例如auto&& t = 10克伊,當auto被推演為int酥郭,則auto&& t推演為int&& t,與原來它持有右值剛好匹配愿吹。



通用初始化:Braced Initialization

這是templateauto類型推演能力之間存在的唯一差別不从。

右值引用

「右值引用」(Rvalue Reference) 與「通用引用」(Universal Reference)是兩個不同的概念,非常容易混淆犁跪,本文試圖揭示兩者之間的本質的差異椿息。

左值與右值

「左值」與「右值」并非C++11的產(chǎn)物,早已是C++類型系統(tǒng)的一部分了坷衍,并且兩者之間存在明顯的區(qū)別寝优。

舉個例子,進一步明細兩者之間的差異枫耳。此處使用auto&&Universal Reference乏矾,它會根據(jù)「左值」自動推演為「左值引用」,而「右值」推演為「右值引用」。

右值引用

C++98中妻熊,只存在「左值引用」,遺恨缺失「右值引用」的概念仑最,也因此丟失了部分性能優(yōu)化的空間扔役。C++11中引入了「右值引用」,彌補之前的過失警医,結合「移動」(move)的機制亿胸,進一步提高了C++在特殊場景的性能。

所謂右值引用预皇,即「右值」的引用侈玄;之前慣稱的「引用」,其實是「左值引用」的簡稱吟温⌒蛳桑「左值引用」只能引用「左值」,「右值引用」只能引用「右值」鲁豪。

通用引用

「通用引用」并非「左值引用」潘悼,即使它們之間都具有&&的語法結構∨老穑「通用引用」即可以持有「左值」治唤,也可以持有「右值」,是一種「通用」的引用類型糙申。而「右值引用」只能引用「右值」宾添。

特征

  • void f(Object&& o),因為未發(fā)生類型推演柜裸,為右值引用
  • template <typename T> void f(std::vector<T>&& v)缕陕,因為不是T&&的句法結構,為右值引用

可以簡單歸納之疙挺,「通用引用」出現(xiàn)于如下兩種常見:

template <typename T>
void f(T&& t);

auto&& r = i;

樣例

std::vector新增加的「右值引用」的push_back榄檬,及其「通用引用」的emplace_back是最好的案例。

剖析std::move

C++11實現(xiàn)

當傳遞左值時

經(jīng)過如下的類型推演過程衔统,當傳遞「左值」時鹿榜,std::move強制轉為換「右值引用」。

當傳遞右值時

經(jīng)過如下的類型推演過程锦爵,當傳遞「右值」時舱殿,std::move順水推舟隔节,傳遞「右值引用」豌鹤。綜上述,借助「通用引用」的能力妒御,std::move其實完成了「無條件的」右值引用轉換規(guī)則樟氢。

C++14改進實現(xiàn)

剖析std::forward

C++11實現(xiàn)

當傳遞左值時

經(jīng)過如下的類型推演過程得知冈绊,當傳遞「左值」時侠鳄,std::forward完成「左值」的「轉發(fā)」機制。

當傳遞右值時

經(jīng)過如下的類型推演過程得知死宣,當傳遞「右值」時伟恶,std::forward也完成「右值」的「轉發(fā)」機制。為此毅该,std::forward的機制博秫,完成了C++11的「完美轉換」(Perfect Forward)的機制。

C++14改進實現(xiàn)

習慣用法

回顧

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末眶掌,一起剝皮案震驚了整個濱河市挡育,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌朴爬,老刑警劉巖即寒,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異召噩,居然都是意外死亡蒿叠,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進店門蚣常,熙熙樓的掌柜王于貴愁眉苦臉地迎上來市咽,“玉大人,你說我怎么就攤上這事抵蚊∈┮铮” “怎么了?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵贞绳,是天一觀的道長谷醉。 經(jīng)常有香客問我,道長冈闭,這世上最難降的妖魔是什么俱尼? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮萎攒,結果婚禮上遇八,老公的妹妹穿的比我還像新娘。我一直安慰自己耍休,他們只是感情好刃永,可當我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著羊精,像睡著了一般斯够。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天读规,我揣著相機與錄音抓督,去河邊找鬼。 笑死束亏,一個胖子當著我的面吹牛铃在,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播枪汪,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼怔昨!你這毒婦竟也來了雀久?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤趁舀,失蹤者是張志新(化名)和其女友劉穎赖捌,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體矮烹,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡越庇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了奉狈。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片卤唉。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖仁期,靈堂內(nèi)的尸體忽然破棺而出桑驱,到底是詐尸還是另有隱情,我是刑警寧澤跛蛋,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布熬的,位于F島的核電站,受9級特大地震影響赊级,放射性物質發(fā)生泄漏押框。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一理逊、第九天 我趴在偏房一處隱蔽的房頂上張望橡伞。 院中可真熱鬧,春花似錦晋被、人聲如沸骑歹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽道媚。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間最域,已是汗流浹背谴分。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留镀脂,地道東北人牺蹄。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像薄翅,于是被迫代替她去往敵國和親沙兰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,922評論 2 361

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