基本信息
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++的後續版本 。
版本變更
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,或是其他符合範圍概念的對象。
功能 | VS2011 | VS2013 | g++ 4.7 | Clang 3.1 |
auto關鍵字 | Yes | Yes | Yes | Yes |
decltype關鍵字 | Yes | Yes | Yes | Yes |
右值引用(Rvalue references)與移動語義(move semantics) | Yes | Yes | Yes | Yes |
Lambda表達式 | Yes | Yes | Yes | Yes |
nullptr關鍵字 | Yes | Yes | Yes | Yes |
靜態斷言(static_assert)關鍵字 | Yes | Yes | Yes | Yes |
基於範圍的循環(Range based for loop)語法 | Yes | Yes | Yes | Yes |
函式返回類型後置(Trailing return type in functions)語法 | Yes | Yes | Yes | Yes |
final關鍵字 | Yes | Yes | Yes | Yes |
override關鍵字 | Yes | Yes | Yes | Yes |
強類型枚舉(Strongly typed enums) | Yes | Yes | Yes | Yes |
前置枚舉聲明(Forward declared enums) | Yes | Yes | Yes | Yes |
外部模板(extern templates) | Yes | Yes | Yes | Yes |
模板右尖括弧嵌套(>> for nested templates) | Yes | Yes | Yes | Yes |
Local and unnamed types as template arguments | Yes | Yes | Yes | Yes |
變參宏(Variadic macros) | Yes | Yes | Yes | Yes |
新內建類型(New built-in types) | Partial(部分) | ? | Yes | Yes |
Initializer_lists容器 | No | ? | Yes | Yes |
顯式類型轉換運算符(explicit type conversion operators) | No | Yes | Yes | Yes |
內聯命名空間(Inline namespaces) | No | ? | Yes | Yes |
sizeof用在沒實例時的非靜態成員 (sizeof on non-static data members without an instance) | No | ? | Yes | Yes |
改變union成員限制(Changed restrictions on union members) | No | ? | Yes | Yes |
Raw string literals | No | Yes | Yes | Yes |
User defined literals | No | ? | Yes | Yes |
Encoding support in literals | No | ? | Yes | Yes |
Arbitrary expressions in template deduction contexts | No | ? | Yes | Yes |
默認方法(Defaulted methods) | No | Yes(有條件支持) | Yes | Yes |
刪除方法(Deleted methods) | No | Yes(有條件支持) | Yes | Yes |
非靜態成員初始化(Non-static data member initializers) | No | ? | Yes | Yes |
變參模板(Variadic templates) | No | ? | Yes | Yes |
函式模板中的默認模板參數 (Default template arguments in function templates) | No | ? | Yes | Yes |
模板別名(Template aliases) | No | ? | Yes | Yes |
前置構造函式(Forwarding constructors) | No | ? | Yes | Yes |
noexcept關鍵字 | No | ? | Yes | Yes |
constexpr關鍵字 | No | ? | Yes | Yes |
Alignment 支持 | Partial(部分) | Partial(部分) | Yes | Yes |
*this的右值引用 | No | ? | No | Yes |
C99兼容性(C99compatibility) | Partial(部分) | Partial(部分) | Partial(部分) | Partial(部分) |
執行緒本地存儲(Thread local storage) | Partial(部分) | Partial(部分) | Partial(部分) | |
構造函式繼承(Inheriting constructors) | No | ? | No | No |
Generalized attributes | No | ? | No | No |
通過對比可以發現,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 Features | Visual Studio 2010 | Visual Studio 2012 | Visual 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: Concurrency | Visual Studio 2010 | Visual Studio 2012 | Visual 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: C99 | Visual Studio 2010 | Visual Studio 2012 | Visual 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 |