国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > C++ > 正文

C++14特性

2019-11-10 22:13:05
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

C++14是C++的現(xiàn)行標(biāo)準(zhǔn)的非正式名稱,正式名稱為"International Standard ISO/IEC 14882:2014(E) PRogramming Language C++"。C++14旨在作為C++11的一個(gè)小擴(kuò)展,主要提供漏洞修復(fù)和小的改進(jìn)。C++14標(biāo)準(zhǔn)的委員會(huì)草案(Committee Draft)N3690于2013年5月15日發(fā)表。[1]工作草案(Working Draft)N3936已于2014年3月2日完成。最終的投票期結(jié)束于2014年8月15日,結(jié)果(一致通過(guò))已于8月18日公布。[2]

目錄

  [隱藏] 1新的語(yǔ)言特性1.1泛型的lambda1.2Lambda捕獲部分中使用表達(dá)式1.3函數(shù)返回類型推導(dǎo)1.4另一種類型推斷1.5放松的constexpr函數(shù)限制1.6變量模板1.7聚合類成員初始化1.8二進(jìn)制字面量1.9數(shù)字分位符1.10deprecated 屬性2新的標(biāo)準(zhǔn)庫(kù)特性2.1共享的互斥體和鎖2.2元函數(shù)的別名2.3關(guān)聯(lián)容器中的異構(gòu)查找2.4標(biāo)準(zhǔn)自定義字面量2.5通過(guò)類型尋址多元組2.6較小的標(biāo)準(zhǔn)庫(kù)特性3已被移除或是不包含在C++14標(biāo)準(zhǔn)的特性3.1關(guān)于數(shù)組的擴(kuò)展3.2Optional值3.3Concepts Lite4另見(jiàn)5參考資料

新的語(yǔ)言特性[編輯]

以下為在C++14中被加入語(yǔ)言核心的特性。

泛型的lambda[編輯]

在C++11中,lambda函數(shù)的形式參數(shù)需要被聲明為具體的類型。C++14放寬了這一要求,允許lambda函數(shù)的形式參數(shù)聲明中使用類型說(shuō)明符auto[3]

auto lambda = [](auto x, auto y) {return x + y;}

泛型lambda函數(shù)遵循模板參數(shù)推導(dǎo)的規(guī)則。以上代碼的作用與下面的代碼相同:[4]

struct unnamed_lambda{  template<typename T, typename U>    auto Operator()(T x, U y) const {return x + y;}};auto lambda = unnamed_lambda{};

Lambda捕獲部分中使用表達(dá)式[編輯]

C++11的lambda函數(shù)通過(guò)值拷貝(by copy)或引用(by reference)捕獲(capture)已在外層作用域聲明的變量。這意味著lambda捕獲的變量不可以是move-only的類型。[5] C++14允許lambda成員用任意的被捕獲表達(dá)式初始化。這既允許了capture by value-move,也允許了任意聲明lambda的成員,而不需要外層作用域有一個(gè)具有相應(yīng)名字的變量。[6]這稱為廣義捕獲(Generalized capture)。[7]即在捕獲子句(capture clause)中增加并初始化新的變量,該變量不需要在lambda表達(dá)式所處的閉包域(enclosing scope)中存在;即使在閉包域中存在也會(huì)被新變量覆蓋(override)。新變量類型由它的初始化表達(dá)式推導(dǎo)。用途是可以從外層作用域中捕獲只供移動(dòng)的變量并使用它。

這是通過(guò)使用一個(gè)初始化表達(dá)式完成的:

auto lambda = [value = 1] {return value;}

lambda函數(shù)lambda的返回值是1,說(shuō)明value被初始化為1。被聲明的捕獲變量的類型會(huì)根據(jù)初始化表達(dá)式推斷,推斷方式與用auto聲明變量相同。

使用標(biāo)準(zhǔn)函數(shù)std::move可以使之被用以通過(guò)move捕獲:

auto ptr = std::make_unique<int>(10); //See below for std::make_uniqueauto lambda = [value = std::move(ptr)] {return *value;}

函數(shù)返回類型推導(dǎo)[編輯]

C++11允許lambda函數(shù)根據(jù)return語(yǔ)句的表達(dá)式類型推斷返回類型。C++14為一般的函數(shù)也提供了這個(gè)能力。C++14還拓展了原有的規(guī)則,使得函數(shù)體并不是{return expression;}形式的函數(shù)也可以使用返回類型推導(dǎo)。[8]

為了啟用返回類型推導(dǎo),函數(shù)聲明必須將auto作為返回類型,但沒(méi)有C++11的后置返回類型說(shuō)明符:

auto DeduceReturnType();   //返回類型由編譯器推斷

如果函數(shù)實(shí)現(xiàn)中含有多個(gè)return語(yǔ)句,這些表達(dá)式必須可以推斷為相同的類型。[9]

使用返回類型推導(dǎo)的函數(shù)可以前向聲明,但在定義之前不可以使用。它們的定義在使用它們的翻譯單元(translation unit)之中必須是可用的。

這樣的函數(shù)中可以存在遞歸,但遞歸調(diào)用必須在函數(shù)定義中的至少一個(gè)return語(yǔ)句之后:[9]

auto Correct(int i) {  if (i == 1)    return i;               // 返回類型被推斷為int  else    return Correct(i-1)+i;  // 正確,可以調(diào)用}auto Wrong(int i){  if(i != 1)    return Wrong(i-1)+i;  // 不能調(diào)用,之前沒(méi)有return語(yǔ)句  else    return i;             // 返回類型被推斷為int}

另一種類型推斷[編輯]

C++11中有兩種推斷類型的方式。auto根據(jù)給出的表達(dá)式產(chǎn)生具有合適類型的變量。decltype可以計(jì)算給出的表達(dá)式的類型。但是,decltypeauto推斷類型的方式是不同的。特別地,auto總是推斷出非引用類型,就好像使用了std::remove_reference一樣,而auto&&總是推斷出引用類型。然而decltype可以根據(jù)表達(dá)式的值類別(value category)和表達(dá)式的性質(zhì)推斷出引用或非引用類型:[8]

int i;int&& f();auto x3a = i;              // x3a的類型是intdecltype(i) x3d = i;       // x3d的類型是intauto x4a = (i);            // x4a的類型是intdecltype((i)) x4d = (i);   // x4d的類型是int&auto x5a = f();            // x5a的類型是intdecltype(f()) x5d = f();   // x5d的類型是int&&

C++14增加了decltype(auto)的語(yǔ)法。允許auto的類型聲明使用decltype的規(guī)則。也即,允許不必顯式指定作為decltype參數(shù)的表達(dá)式,而使用decltype對(duì)于給定表達(dá)式的推斷規(guī)則。

decltype(auto)的語(yǔ)法也可以用于返回類型推導(dǎo),只需用decltype(auto)代替auto[9]

放松的constexpr函數(shù)限制[編輯]

C++11引入了聲明為constexpr的函數(shù)的概念。聲明為constexpr函數(shù)的意義是:如果其參數(shù)均為合適的編譯期常量,則對(duì)這個(gè)constexpr函數(shù)的調(diào)用就可用于期望常量表達(dá)式的場(chǎng)合(如模板的非類型參數(shù),或枚舉常量的值)。如果參數(shù)的值在運(yùn)行期才能確定,或者雖然參數(shù)的值是編譯期常量,但不匹配這個(gè)函數(shù)的要求,則對(duì)這個(gè)函數(shù)調(diào)用的求值只能在運(yùn)行期進(jìn)行。 然而C++11要求constexpr函數(shù)只含有一個(gè)將被返回的表達(dá)式(也可以還含有static_assert聲明等其它語(yǔ)句,但允許的語(yǔ)句類型很少)。

C++14放松了這些限制。聲明為constexpr的函數(shù)可以含有以下內(nèi)容:[8]

任何聲明,除了:staticthread_local變量。沒(méi)有初始化的變量聲明。條件分支語(yǔ)句ifswitch。所有的循環(huán)語(yǔ)句,包括基于范圍的for循環(huán)。表達(dá)式可以改變一個(gè)對(duì)象的值,只需該對(duì)象的生命期在聲明為constexpr的函數(shù)內(nèi)部開(kāi)始。包括對(duì)有constexpr聲明的任何非const非靜態(tài)成員函數(shù)的調(diào)用。

goto仍然不允許在constexpr函數(shù)中出現(xiàn)。

此外,C++11指出,所有被聲明為constexpr的非靜態(tài)成員函數(shù)也隱含聲明為const(即函數(shù)不能修改*this的值)。這點(diǎn)已經(jīng)被刪除,非靜態(tài)成員函數(shù)可以為非const[10]

變量模板[編輯]

在C++之前的版本中,模板可以是函數(shù)模板或類模板(C++11引入了類型別名模板)。C++14現(xiàn)在也可以創(chuàng)建變量模板。在提案中給出的示例是變量pi,其可以被讀取以獲得各種類型的pi的值(例如,當(dāng)被讀取為整數(shù)類型時(shí)為3;當(dāng)被讀取為float,double,long double時(shí),可以是近似floatdoublelong double精度的值)包括特化在內(nèi),通常的模板的規(guī)則都適用于變量模板的聲明和定義。[6][11]

template<typename T>constexpr T pi = T(3.141592653589793238462643383);// 適用于特化規(guī)則 :template<>constexpr const char* pi<const char*> = "pi";

聚合類成員初始化[編輯]

C++11增加了default member initializer,如果構(gòu)造函數(shù)沒(méi)有初始化某個(gè)成員,并且這個(gè)成員擁有default member initializer,就會(huì)用default member initializer來(lái)初始化成員。聚合類(aggregate type)的定義被改為明確排除任何含有default member initializer的類類型,因此,如果一個(gè)類含有default member initializer,就不允許使用聚合初始化。

C++14放松了這一限制,[8]含有default member initializer的類型也允許聚合初始化。如果在定義聚合體類型的對(duì)象時(shí),使用的花括號(hào)初始化列表沒(méi)有指定該成員的值,將會(huì)用default member initializer初始化它。[12]

struct CXX14_aggregate {    int x;    int y = 42;};CXX14_aggregate a = {1}; // C++14允許。a.y被初始化為42

二進(jìn)制字面量[編輯]

C++14的數(shù)字可以用二進(jìn)制形式指定。[8]其格式使用前綴0b0B。這樣的語(yǔ)法也被java、Python、Perl和D語(yǔ)言使用。

數(shù)字分位符[編輯]

C++14引入單引號(hào)(')作為數(shù)字分位符號(hào),使得數(shù)值型的字面量可以具有更好的可讀性。[13]

Ada、D語(yǔ)言、Java、Perl、Ruby等程序設(shè)計(jì)語(yǔ)言使用下劃線(_)作為數(shù)字分位符號(hào),C++之所以不和它們保持一致,是因?yàn)橄聞澗€已被用在用戶自定義的字面量的語(yǔ)法中。

auto integer_literal = 100'0000;auto floating_point_literal = 1.797'693'134'862'315'7E+308;auto binary_literal = 0b0100'1100'0110;auto silly_example = 1'0'0'000'00;

deprecated 屬性[編輯]

deprecated屬性允許標(biāo)記不推薦使用的實(shí)體,該實(shí)體仍然能合法使用,但會(huì)讓用戶注意到使用它是不受歡迎的,并且可能會(huì)導(dǎo)致在編譯期間輸出警告消息。 deprecated可以有一個(gè)可選的字符串文字作為參數(shù),以解釋棄用的原因和/或建議替代者。

[[deprecated]] int f();[[deprecated("g() is thread-unsafe. Use h() instead")]]void g( int& x );void h( int& x );void test() {  int a = f(); // 警告:'f'已棄用  g(a); // 警告:'g'已棄用:g() is thread-unsafe. Use h() instead}

新的標(biāo)準(zhǔn)庫(kù)特性[編輯]

共享的互斥體和鎖[編輯]

C++14增加了一類共享的互斥體和相應(yīng)的共享鎖[14][15]。起初選擇的名字是std::shared_mutex,但由于后來(lái)增加了與std::timed_mutex相似的特性,std::shared_timed_mutex成為了更適合的名字。[16]

元函數(shù)的別名[編輯]

C++11定義了一組元函數(shù),用于查詢一個(gè)給定類型是否具有某種特征,或者轉(zhuǎn)換給定類型的某種特征,從而得到另一個(gè)類型。后一種元函數(shù)通過(guò)成員類型type來(lái)返回轉(zhuǎn)換后的類型,當(dāng)它們用在模板中時(shí),必須使用typename關(guān)鍵字,這會(huì)增加代碼的長(zhǎng)度。

template <class T>type_object<  typename std::remove_cv<    typename std::remove_reference<T>::type  >::type>get_type_object(T&);

利用類型別名模板,C++14提供了更便捷的寫法。其命名規(guī)則是:如果標(biāo)準(zhǔn)庫(kù)的某個(gè)類模板(假設(shè)為std::some_class)只含有唯一的成員,即成員類型type,那么標(biāo)準(zhǔn)庫(kù)提供std::some_class_t<T>作為typename std::some_class::type的別名。

在C++14,擁有類型別名的元函數(shù)包括:remove_const、remove_volatile、remove_cv、add_const、add_volatile、add_cv、remove_reference、add_lvalue_reference、add_rvalue_reference、make_signed、make_unsigned、remove_extent、remove_all_extents、remove_pointer、add_pointer、aligned_storage、aligned_union、decay、enable_if、conditional、common_type、underlying_type、result_of、tuple_element。

template <class T>type_object<std::remove_cv_t<std::remove_reference_t<T>>>get_type_object(T&);

關(guān)聯(lián)容器中的異構(gòu)查找[編輯]

C++標(biāo)準(zhǔn)庫(kù)定義了四個(gè)關(guān)聯(lián)容器類。set和multiset允許用戶根據(jù)一個(gè)值在容器中查找對(duì)應(yīng)的的同類型的值。map和multimap容器允許用戶指定鍵(key)和值(value)的類型,根據(jù)鍵進(jìn)行查找并返回對(duì)應(yīng)的值。然而,查找只能接受指定類型的參數(shù),在map和multimap中是鍵的類型,而在set和multiset容器中就是值本身的類型。

C++14允許通過(guò)其他類型進(jìn)行查找,只需要這個(gè)類型和實(shí)際的鍵類型之間可以進(jìn)行比較操作。[17]這允許std::set<std::string>使用const char*,或任何可以通過(guò)operator< 與std::string比較的類型作為查找的參數(shù)。

為保證向后兼容性,這種異構(gòu)查找只在提供給關(guān)聯(lián)容器的比較器允許的情況下有效。標(biāo)準(zhǔn)庫(kù)的泛型比較器,如std::less<>std::greater<>允許異構(gòu)查找。[18]

標(biāo)準(zhǔn)自定義字面量[編輯]

C++11增加了自定義字面量(user-defined literals)的特性,使用戶能夠定義新的字面量后綴,但標(biāo)準(zhǔn)庫(kù)并沒(méi)有對(duì)這一特性加以利用。C++14標(biāo)準(zhǔn)庫(kù)定義了以下字面量后綴:[17]

"s",用于創(chuàng)建各種std::basic_string類型。"h"、"min"、"s"、"ms"、"us"、"ns",用于創(chuàng)建相應(yīng)的std::chrono::duration時(shí)間間隔。"if"、"i"、"il"用于創(chuàng)建相應(yīng)的 std::complex<float>、 std::complex<double> 和 std::complex<long double> 復(fù)數(shù)類型。
auto str = "hello world"s; // 自動(dòng)推導(dǎo)為 std::stringauto dur = 60s;            // 自動(dòng)推導(dǎo)為 chrono::secondsauto z   = 1i;             // 自動(dòng)推導(dǎo)為 complex<double>

兩個(gè)"s"互不干擾,因?yàn)楸硎咀址闹荒軐?duì)字符串字面量操作,而表示秒的只針對(duì)數(shù)字。[19]

通過(guò)類型尋址多元組[編輯]

C++11引入的std::tuple類型允許不同類型的值的聚合體用編譯期整型常數(shù)索引。C++14還允許使用類型代替常數(shù)索引,從多元組中獲取對(duì)象。[17]若多元組含有多于一個(gè)這個(gè)類型的對(duì)象,將會(huì)產(chǎn)生一個(gè)編譯錯(cuò)誤:[20]

tuple<string, string, int> t("foo", "bar", 7);int i = get<int>(t);        // i == 7int j = get<2>(t);          // Same as before: j == 7string s = get<string>(t);  //Compiler error due to ambiguity

較小的標(biāo)準(zhǔn)庫(kù)特性[編輯]

std::make_unique可以像std::make_shared一樣使用,用于產(chǎn)生std::unique_ptr對(duì)象。[6]

std::is_final,用于識(shí)別一個(gè)class類型是否禁止被繼承。

std::integral_constant增加了一個(gè)返回常量值的operator()[17]

全局std::begin/std::end函數(shù)之外,增加了std::cbegin/std::cend函數(shù),它們總是返回常量迭代器(constant iterators)。

已被移除或是不包含在C++14標(biāo)準(zhǔn)的特性[編輯]

因?yàn)镃++14的主要目的是漏洞修復(fù)和小的改進(jìn),一些重量級(jí)的特性被從C++14中移除,其中有部分將加入C++17標(biāo)準(zhǔn)。

關(guān)于數(shù)組的擴(kuò)展[編輯]

在C++11和之前的標(biāo)準(zhǔn)中,在堆棧上分配的數(shù)組被限制為擁有一個(gè)固定的、編譯期確定的長(zhǎng)度。這一擴(kuò)展允許在堆棧上分配的一個(gè)數(shù)組的最后一維具有運(yùn)行期確定的長(zhǎng)度。[6]

運(yùn)行期確定長(zhǎng)度的數(shù)組不可以作為對(duì)象的一部分,也不可以具有全局存儲(chǔ)期,他們只能被聲明為局部變量。運(yùn)行期確定長(zhǎng)度的數(shù)組也可以使用C++11的基于范圍的for循環(huán)。[21]

同時(shí)還將添加std::dynarray類型,它擁有與std::vectorstd::array相似的接口。代表一個(gè)固定長(zhǎng)度的數(shù)組,其大小在運(yùn)行期構(gòu)造對(duì)象時(shí)確定。std::dynarray類被明顯地設(shè)計(jì)為當(dāng)它被放置在棧上時(shí)(直接放置在棧上,或作為另一個(gè)棧對(duì)象的成員),可以使用棧內(nèi)存而不是堆內(nèi)存。

由于一些設(shè)計(jì)無(wú)法達(dá)成一致,這一擴(kuò)展已被放棄。

Optional值[編輯]

類似于C#中的可空類型,optional類型可能含有或不含有一個(gè)值。這一類型基于Boost的boost::optional類,而添加了C++11和C++14中的新特性,諸如移動(dòng)和in-place構(gòu)造。它不允許用在引用類型上。這個(gè)類被專門的設(shè)計(jì)為一個(gè)literal type(如果模板參數(shù)本身是一個(gè)literal type),因此,它在必要的情況下含有constexpr構(gòu)造函數(shù)。[22]

Concepts Lite[編輯]

參見(jiàn):概念 (C++)

被C++11拒絕后,Concepts受到徹底的修改。Concepts Lite是Concepts的一個(gè)部分,僅包含類型約束,而不含concept_mapaxiom[23]。 ISO/IEC TS 19217:2015 Information technology -- Programming languages -- C++ Extensions for concepts已出版。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 商河县| 华阴市| 定州市| 荥阳市| 莎车县| 丹凤县| 共和县| 阳江市| 长白| 射洪县| 梁山县| 宁陕县| 鄂州市| 成安县| 昌图县| 安阳市| 荆门市| 长泰县| 庆安县| 南靖县| 青浦区| 仙游县| 涞水县| 连平县| 左权县| 元谋县| 新邵县| 抚顺县| 榕江县| 海门市| 当雄县| 阿荣旗| 西华县| 五原县| 哈尔滨市| 舒城县| 南京市| 宁德市| 上栗县| 吐鲁番市| 湘潭县|