C++11

C++11

C++11標準是 ISO/IEC 14882:2011 - Information technology -- Programming languages -- C++ 的簡稱 。 C++11標準由國際標準化組織(ISO)和國際電工委員會(IEC)旗下的C++標準委員會(ISO/IEC JTC1/SC22/WG21)於2011年8月12日公布 ,並於2011年9月出版。2012年2月28日的國際標準草案(N3376)是最接近於C++11標準的草案(僅編輯上的修正)。此次標準為C++98發布後13年來第一次重大修正。

基本信息

C++11標準為C++程式語言的第三個官方標準,正式名叫ISO/IEC 14882:2011 - Information technology -- Programming languages -- C++ 。 在正式標準發布前,原名C++0x。它將取代C++標準第二版ISO/IEC 14882:2003 - Programming languages -- C++ 成為C++語言新標準。

C++11包含了核心語言的新機能,並且拓展C++標準程式庫,並且加入了大部分的C++ Technical Report 1程式庫(數學上的特殊函式除外)。C++ 標準委員會計畫在2010年8月之前完成對最終委員會草案的投票,以及於2011年3月3召開的標準會議完成國際標準的最終草案。最終於2011年8月12日公布,並於2011年9月出版。2012年2月28日的國際標準草案(N3376)是最接近於現行標準的草案(編輯上的修正)。此次標準為13年第一次重大修正。

ISO將在2014年和2017年發布C++的後續版本 。

C++語言的標準化進程 C++語言的標準化進程

版本變更

1.對C++核心語言的擴充

2.核心語言運行期的強化(右值引用和 move 語義;泛化的常數表達式;對POD定義的修正)

3.核心語言建構期表現的加強(外部模板)

4.核心語言使用性的加強(初始化列表;統一的初始化;類型推導[auto關鍵字];以範圍為基礎的 for 循環;Lambda函式與表示法;另一種的函式語法;對象構建的改良;顯式虛函式重載;空指針;強類型枚舉;角括弧;顯式類型轉換;模板的別名;無限制的unions)

5.核心語言能力的提升(變長參數模板;新的字元串字面值;用戶自定義的字面值;多任務存儲器模型;thread-local的存儲期限;使用或禁用對象的默認函式;long long int 類型;靜態assertion;允許sizeof運算符作用在類型的數據成員上,無需明確的對象;)

6.C++標準程式庫的變更(標準庫組件的升級;執行緒支持;多元組類型;散列表;正則表達式;通用智慧型指針;可擴展的隨機數功能;包裝引用;多態函式對象包裝器;用於元編程的類型屬性;用於計算函式對象返回類型的統一方法)

現狀

編譯器實現情況 編譯器實現情況

每個標準的發布都需要一段時間的普及。包括技術圖書,編譯器支持。C++11標準發布後,美國已經更新了大部分著名C++圖書,以支持最新的C++11標準,例如:《C++ Primer (Fifth Edition)》、《C++ Primer Plus (Sixth Edition)》、《The C++ Programming Language (4th Edition)》等等。這幾本書都已經有了中文翻譯版,分別名叫《C++ Primer 中文版(第五版)》、《C++ Primer Plus 中文版(第六版)》、《C++程式設計語言(第四版)》。各大主流編譯器產商也逐步添加了對C++11語法的支持,例如VS2012、g++、clang等都在很大程度上支持C++11標準。圖為迄今支持情況。

示例

類型推導與auto關鍵字

C++ 11 標準廢除了舊的 C++ 98 標準中 auto 的意思(自動變數類型),改成了自動類型推導的意思。

在標準C/C++,使用變數必須明確的指出其類型(強類型)。然而隨著模板類型的出現以及模版元編程的技巧,指定類型,特別是函式定義明確的指定返回類型,就不容易表示。在這樣的情況下,將中間結果存儲與變數是一件困難的事情,可能會需要知道特定的元編程程式庫的內部情況。

C++11提供了兩種方法緩解上述所遇到的困難。首先被有明確初始化的變數可以使用auto關鍵字。這會依據該初始化式的具體類型產生變數。示例:

otherVariable 的類是明確定義的。因為5的類型是int,所以編譯器按照“int otherVariable =5;”來編譯。

someStrangeCallableType 的類型是模版函式 boost::bind對特定引數返回的類型,作為編譯器語義分析的一部分,這個類型能夠簡單地被編譯器決定,但用戶要通過查看來判斷類型就不是一件容易的事情。

除此之外,C++11還定義了 decltype 能夠被用來在編譯器決定一個表達式的類型。舉例:

decltype 和 auto 一起使用會更為有用,因為 auto 變數的類型只有編譯器知道。然而 decltype 對於那些大量運用運算符重載和特化的類型的代碼的表示也非常有用。

auto 對於減少冗贅的代碼也很有用。舉例而言,程式設計師不用寫像下面這樣:

可以使用auto簡化為:

這項差異隨著程式設計師開始嵌套容器而更為顯著,雖然在這種情況下 typedef 是一個減少代碼的好方法。

decltype 所表示的類型可以和 auto 推導出來的不同。

外部模板

在標準C++中,只要在編譯單元內遇到被完整定義的模板,編譯器都必須將其實例化(instantiate)。這會大大增加編譯時間,特別是模板在許多編譯單元內使用相同的參數實例化。看起來沒有辦法告訴C++不要引發模板的實例化。

C++11將會引入外部模板這一概念。C++已經有了強制編譯器在特定位置開始實例化的語法:

template class std::vector<MyClass>;

而C++所缺乏的是阻止編譯器在某個編譯單元內實例化模板的能力。C++11將簡單地擴充前文語法如下:

extern template class std::vector<MyClass>;

這樣就告訴編譯器 不要在該編譯單元內將該模板實例化。

以範圍為基礎的for循環

Boost C++ 定義了許多"範圍 (range) "的概念。範圍表現有如受控制的串列 (list),持有容器中的兩點。有序容器是範圍概念的超集 (superset),有序容器中的兩個疊代器 (iterator) 也能定義一個範圍。這些概念以及操作的算法,將被併入 C++11 標準程式庫。不過 C++11 將會以語言層次的支持來提供範圍概念的效用。

for 語句將允許簡單的範圍疊代:第一部分定義被用來做範圍疊代的變數,就像被聲明在一般for循環的變數一樣,其作用域僅只於循環的範圍。而在":"之後的第二區塊,代表將被疊代的範圍。這樣一來,就有了能夠允許C-style數組被轉換成範圍概念的概念圖。這可以是std::vector,或是其他符合範圍概念的對象。

編譯器支持
功能VS2011VS2013g++ 4.7Clang 3.1
auto關鍵字YesYesYesYes
decltype關鍵字YesYesYesYes
右值引用(Rvalue references)與移動語義(move semantics)YesYesYesYes
Lambda表達式YesYesYesYes
nullptr關鍵字YesYesYesYes
靜態斷言(static_assert)關鍵字 YesYesYesYes
基於範圍的循環(Range based for loop)語法 YesYesYesYes
函式返回類型後置(Trailing return type in functions)語法YesYesYesYes
final關鍵字YesYesYesYes
override關鍵字YesYesYesYes
強類型枚舉(Strongly typed enums)YesYesYesYes
前置枚舉聲明(Forward declared enums)YesYesYesYes
外部模板(extern templates)YesYesYesYes
模板右尖括弧嵌套(>> for nested templates)YesYesYesYes
Local and unnamed types as template argumentsYesYesYesYes
變參宏(Variadic macros)YesYesYesYes
新內建類型(New built-in types)Partial(部分)?YesYes
Initializer_lists容器No?YesYes
顯式類型轉換運算符(explicit type conversion operators)NoYesYesYes
內聯命名空間(Inline namespaces)No?YesYes
sizeof用在沒實例時的非靜態成員 (sizeof on non-static data members without an instance) No?YesYes
改變union成員限制(Changed restrictions on union members)No?YesYes
Raw string literalsNoYesYesYes
User defined literalsNo?YesYes
Encoding support in literalsNo?YesYes
Arbitrary expressions in template deduction contextsNo?YesYes
默認方法(Defaulted methods)NoYes(有條件支持) YesYes
刪除方法(Deleted methods)NoYes(有條件支持) YesYes
非靜態成員初始化(Non-static data member initializers)No?YesYes
變參模板(Variadic templates)No?YesYes
函式模板中的默認模板參數 (Default template arguments in function templates) No?YesYes
模板別名(Template aliases)No?YesYes
前置構造函式(Forwarding constructors)No?YesYes
noexcept關鍵字No?YesYes
constexpr關鍵字No?YesYes
Alignment 支持Partial(部分)Partial(部分)YesYes
*this的右值引用No?NoYes
C99兼容性(C99compatibility)Partial(部分)Partial(部分)Partial(部分)Partial(部分)
執行緒本地存儲(Thread local storage)Partial(部分)Partial(部分)Partial(部分)
構造函式繼承(Inheriting constructors)No?NoNo
Generalized attributesNo?NoNo

通過對比可以發現,Clang在大多數C++11功能實現上處於領先地位,而Visual Studio則稍顯落後。當然,這三個編譯器都有著不錯的子集適用於跨平台開發。( 註:GCC4.8.1已完全支持C++11,Clang 3.3 也完全支持了C++11。最新版本的Linux 發行版(RHEL 7,CentOS 7,Ubuntu 14.06,都自帶了完全支持C++11的編譯器)

你可以使用類型推斷、移動語義、右值引用、nullptr,static_assert,range-based參考對比。同時你還可以使用最終和重寫關鍵字來進行友好的控制。此外,你還可以通過Enums(例舉)強類型和提前聲明,這裡有幾個改進後的模板包括extern keyword。

遺憾的是,Visual Studio並不支持較多請求的可變參數模板。另一方面,可變參數宏在這三款編譯器中只支持C99標準。繼承構造函式和廣義屬性這些特性並不是在任何地方都能獲得支持。本地執行緒存儲是是支持情況最好的一部分(通過非關鍵字標準)。

下面給出在msdn中列舉的對C++功能的支持

功能支持表

以下是Microsoft Visual Studio 2010,2012,2013對C++11支持的比較 。

C++11 Core Language FeaturesVisual Studio 2010Visual Studio 2012Visual Studio 2013
Rvalue referencesv0.1,v1.0,v2.0,v2.1,v3.0 v2.0 v2.1* v2.1*
ref-qualifiers No No No
Non-static data member initializers No No Yes
Variadic templatesv0.9,v1.0 No No Yes
Initializer lists No No Yes
static_assert Yes Yes Yes
autov0.9,v1.0 v1.0 v1.0 v1.0
Trailing return types Yes Yes Yes
Lambdasv0.9,v1.0,v1.1 v1.0 v1.1 v1.1
decltypev1.0,v1.1 v1.0 v1.1** v1.1
Right angle brackets Yes Yes Yes
Default template arguments for function templates No No Yes
Expression SFINAE No No No
Alias templates No No Yes
Extern templates Yes Yes Yes
nullptr Yes Yes Yes
Strongly typed enums Partial Yes Yes
Forward declared enums No Yes Yes
Attributes No No No
constexpr No No No
Alignment TR1 Partial Partial
Delegating constructors No No Yes
Inheriting constructors No No No
Explicit conversion operators No No Yes
char16_t/char32_t No No No
Unicode string literals No No No
Raw string literals No No Yes
Universal character names in literals No No No
User-defined literals No No No
Standard-layout and trivial types No Yes Yes
Defaulted and deleted functions No No Yes*
Extended friend declarations Yes Yes Yes
Extended sizeof No No No
Inline namespaces No No No
Unrestricted unions No No No
Local and unnamed types as template arguments Yes Yes Yes
Range-based for-loop No Yes Yes
override and finalv0.8,v0.9,v1.0 Partial Yes Yes
Minimal GC support Yes Yes Yes
noexcept No No No

並發能力

C++11 Core Language Features: ConcurrencyVisual Studio 2010Visual Studio 2012Visual Studio 2013
Reworded sequence points N/A N/A N/A
Atomics No Yes Yes
Strong compare and exchange No Yes Yes
Bidirectional fences No Yes Yes
Memory model N/A N/A N/A
Data-dependency ordering No Yes Yes
Data-dependency ordering: function annotation No No No
exception_ptr Yes Yes Yes
quick_exit No No No
Atomics in signal handlers No No No
Thread-local storage Partial Partial Partial
Magic statics No No No

語言功能支持

C++11 Core Language Features: C99Visual Studio 2010Visual Studio 2012Visual Studio 2013
__func__ Partial Partial Partial
C99 preprocessor Partial Partial Partial
long long Yes Yes Yes
Extended integer types N/A N/A N/A

相關詞條

相關搜尋

熱門詞條

聯絡我們