C++ 11 功能 (現代的 C++)
本文件說明功能新 C++ 標準也稱為 C++11 在 Visual C++ 中實作。
C++11 核心語言功能
Visual C++ 2010 實作了 C++0x 核心語言規格的許多功能,是目前 C++11的,因此, Visual Studio 2012 中的 Visual C++ 會展開包含許多 C++11 功能。下表列出 C++11 核心語言功能和其實作狀態在 Visual C++ 2010 和 Visual Studio 2012 中的 Visual C++。
VC10 |
VC11 |
|
---|---|---|
v2.0 |
v2.1* |
|
否 |
否 |
|
否 |
否 |
|
否 |
否 |
|
否 |
否 |
|
是 |
是 |
|
v1.0 |
v1.0 |
|
是 |
是 |
|
v1.0 |
v1.1 |
|
v1.0 |
v1.1 ** |
|
是 |
是 |
|
否 |
否 |
|
否 |
否 |
|
否 |
否 |
|
是 |
是 |
|
是 |
是 |
|
Partial |
是 |
|
否 |
是 |
|
否 |
否 |
|
否 |
否 |
|
TR1 |
Partial |
|
否 |
否 |
|
否 |
否 |
|
否 |
否 |
|
否 |
否 |
|
否 |
否 |
|
否 |
否 |
|
否 |
否 |
|
否 |
否 |
|
否 |
是 |
|
否 |
否 |
|
是 |
是 |
|
否 |
否 |
|
否 |
否 |
|
否 |
否 |
|
是 |
是 |
|
否 |
是 |
|
Partial |
是 |
|
是 |
是 |
|
否 |
否 |
C++11 核心語言功能:並行 |
VC10 |
VC11 |
---|---|---|
N/A |
N/A |
|
否 |
是 |
|
否 |
是 |
|
否 |
是 |
|
N/A |
N/A |
|
否 |
是 |
|
否 |
否 |
|
是 |
是 |
|
否 |
否 |
|
否 |
否 |
|
Partial |
Partial |
|
否 |
否 |
C++11 核心語言功能:C99 |
VC10 |
VC11 |
---|---|---|
Partial |
Partial |
|
Partial |
Partial |
|
是 |
是 |
|
N/A |
N/A |
這對資訊的快速輔助在資料表中。
Rvalue 參考
N1610 「類別的初始化狀態由 rvalues 物件」 沒有右值參考,是早期嘗試啟用移動語意。為這個討論,我們命名為「右值參考 v0.1」。由「rvalue 參考 v1.0代替」。「Rvalue 參考 v2.0」,就是 Visual C++ 2010 的工作為基礎,不允許 rvalue 參考繫結至左值藉此解決一個主要安全性問題。「Rvalue 參考 v2.1「修改這個規則。考慮 vector<string>::push_back(),有多載 push_back(const string&) 和 push_back(string&&)呼叫 v.push_back("strval")。"strval" 運算式是字串,因此,它是左值。(換言之,例如整數 1729,是 rvalues,不過,字串常值是特殊的,因為它們是陣列)。右值參考 v2.0 規則說明, string&& 無法繫結到 "strval" ,因為 "strval" 是左值,因此, push_back(const string&) 是唯一可用的多載。這會建立暫存 std::string,將它複製到向量,然後終結暫存 std::string。這不是很有效率。右值參考 v2.1 規則視為 "strval" 繫結的 string&& 將建立暫時的,則為 std::string,而暫存的是右值。因此, push_back(const string&) 和 push_back(string&&) 是可用的,因此, push_back(string&&) 偏好。暫存 std::string 建構,然後將向量。這會更有效率。
在特定情況下「Rvalue 參考 v3.0加入新規則自動產生移動建構函式和移動指派運算子。不過,這在 Visual Studio 2012 中的 Visual C++中,因為未實作所需的時間和資源條件約束。
![]() |
---|
v0.1, v1.0, v2.0, v2.1 v3.0,指定為了清楚起見被發明和顯示 C++11. 的進展。 |
Lambdas
在 lambda 函式 輪詢至工作憑證 (版本 0.9) 之後,就可以變更 Lambda 加入 (版本 1.0),標準化委員會翻修了文字。這個所產生的 Lambda 版本 1.1。這在 Visual C++ 2010太晚發生合併,不過,它在 Visual Studio 2012 中的 Visual C++。Lambda v1.1 文書釐清以及邊角案例應該產生想要參考靜態成員或巢狀 Lambda。這個修復由複雜 Lambda 觸發的 Bug。此外在 Visual Studio 2012 中的 Visual C++中,無狀態 Lambda 轉換為函式指標。這不在 N2927 用語,不過,它還是計數做為 Lambda v1.1 的一部分。FDIS 5.1.2 expr.prim.lambda]/[6 有這個描述:「的 Lambda 運算式的關閉類型沒有 Lambda 擷取具有公用非虛擬非明確常數轉換函式指標至函式的參數和傳回型別和結束型別的函式呼叫運算子相同。這個轉換函式傳回的值將是函式的位址,,當叫用,其效果與叫用結束型別的函式呼叫運算子相同」。( Visual Studio 2012 中的 Visual C++ 相比,好,因為我們設為狀態 Lambda 轉換函式有任意呼叫慣例的指標。這很重要,當您使用需要與 __stdcall 函式指標的位置上) 的 API)
decltype
在 decltype 輪詢至工作憑證 (版本 1.0) 之後,它的最後一個 Minute 接收一小,但是重要 Bug 修正 (版本 1.1)。這是大感興趣在 STL 和優先權的工作的程式設計人員。
強型別/向前宣告列舉
強型別列舉 在 Visual C++ 2010 (特別是,如需明確指定的基礎型別區段的部分支援)。Visual Studio 2012 中的 Visual C++ 完整實作它們,因此完整實作 C++11 語意 向前宣告列舉。
對齊方式
Visual C++ 2010 和 Visual Studio 2012 中的 Visual C++ 實作核心語言關鍵字 alignas來回輪詢輸入工作憑證的 對齊提議alignof 。Visual C++ 2010 會從 TR1 的 aligned_storage 。Visual Studio 2012 中的 Visual C++ 會將 aligned_union 和 std::align() 到標準程式庫。
標準配置和一般型別
公開的變更是從 N2342 「重新造訪的 POD 的;解析核心問題修正 568 (5)」is_trivial 和 is_standard_layout 加入至 <type_traits>。(N2342 調整了大量的核心語言文字,不過,編譯器變更不是必要的)。這些型別特性可用於 Visual C++ 2010,但是,重複 is_pod。因此,資料表之前在文件中「不支援」。在 Visual Studio 2012 中的 Visual C++中,它們是設計給正確解答的編譯器攔截提供動態。
覆寫與 Final
這會經歷短,但是複雜的進展。一開始,, 版本 0.8[override]], [hiding]] 和 [base_check]] 屬性。然後, 版本 0.9屬性是內容關鍵字排除並取代。最後,,版本 1.0它們已減少到「final」在類別和 <override> 和 <final> 函式。這使得它成為遞增的擴充功能,因為 Visual C++ 2010 已經支援函式之「override」語法,而且有語意合法存取那些在 C++11。「final會支援,不過,在其他拼字下「密封」。在 Visual Studio 2012中, 「override」和「final」標準拼字和語意完全支援。如需詳細資訊,請參閱override 規範與final 規範。
原子和詳細
原子, 強式比較和交換, 雙向柵欄,和 資料相依性順序 會指定標準程式庫的輸送帶連結,在 Visual Studio 2012 中的 Visual C++中實作。
標準程式庫功能
該報表核心語言。如需 C++11 標準程式庫,我們沒有功能的格式化的資料表,不過, Visual Studio 2012 中的 Visual C++ 實作,它有兩個例外狀況。首先,在中,當程式庫功能是由編譯器所沒有的功能時,我們可能會模擬所要求 (例如,我們模仿 make_shared<T>()的 variadic 範本—或-我們不實作之後,值得注意的是,只有少數情況 <initializer_list>。其次, C99 標準程式庫,由參考合併到 C++11 標準程式庫裡,主要未實作,不過, Visual C++ 2010中的 <stdint.h> 實作。這在 Visual Studio 2012 中的 Visual C++中的變更部分清單:
新的標題:<atomic>, <chrono>、 <condition_variable>、 <future>、 <mutex>、 <ratio>、 <scoped_allocator>和 <thread>。
根據 C++11, emplace()/emplace_front()/emplace_back()/emplace_hint()/emplace_after() 要求的當地語系化: 在「選擇性引數」number (請參閱虛擬 false variadics > 一節) 所有容器實作。例如, vector<T> 有「template <typename... Args> void emplace_back(Args&&... args)」直接建構項目型別 T 向量中的後面從任意數目的選擇性引數,完全轉送。這比 push_back(T&&)更有效率,需要額外移動建構和解構。
**虛擬 variadics false:**Visual Studio 2012 中的 Visual C++ 有模擬 variadic 範本新的配置。在 Visual C++ 2008 和 Visual C++ 2010SP1, subheaders 重複包含有不同都會定義巨集,排除絕對 0, 1, 2, 3,或多個引數的多載。例如, <memory> 重複包含內部 subheader <xxshared> ,排除絕對 make_shared<T>(args, args, args)。在 Visual Studio 2012 中的 Visual C++中, subheaders 移至。出現在 variadic 範本定義為巨集 (包含太多反斜線繼續) 使用主要巨集,,然後展開。這個內部實作變更具有下列效果:
程式碼會更容易維護,更容易使用 (將 subheaders 是適當數目的工作),且更容易讀取。
逐步執行與偵錯工具抱歉難以!
std::pairpair(piecewise_construct_t, tuple<Args1...>, tuple<Args2...>) 建構函式有「有趣的」效果。這個要求 N^2 多載 (如果我們支援 10 個決策,那表示 121 太多載,,因為 null Tuple 計數此處,)。
傳送相同的訊息到多個新聞群組多對多個多載,加上任何當地語系化多載,在編輯時耗用大量的記憶體。因此,我們已減少無限。在 Visual C++ 2008 和 Visual C++ 2010SP1,無限是 10 (即「variadic」樣板支援 0 到 10 引數,包含)。根據預設,無限 5 是在 Visual Studio 2012 中的 Visual C++。這讓編譯器記憶體消耗量回到為何在 Visual C++ 2010。如果您需要更多引數 (例如,因此,如果您有使用 6 個) 的現有程式碼,有究竟匯出。您可以定義 _VARIADIC_MAX 專案在 5 和 10 (含) 之間。這會耗用更多記憶體,而且可能需要使用 /Zm 編譯器選項為先行編譯標頭檔保留的空間。
**隨機:**uniform_int_distribution 現在已經完成公平性的,因此, shuffle() 在 <algorithm>實作,直接接受與 mersenne_twister的一致的亂數產生器。
對多載的傳址運算子的計數器: C++98/03 禁止的 STL 容器中的項目可以多載其傳址運算子。這是什麼分類與 CComPtr 進行,因此,要求與 CAdapt 的 Helper 類別來保護從這種多載的 STL。在 Visual C++ 2010的開發期間, STL 變更會拒絕更情況的傳址運算子。C++11 變更要求讓多載的傳址運算子可接受。C++11 和 Visual C++ 2010,提供 Helper 函式 std::addressof(),不管運算子多載,可以取得物件真正的位址。在釋放目前 Visual C++ 2010 ,我們會嘗試用「std::addressof(elem)」取代「&elem」的事件,也會有抵抗性。在 Visual Studio 2012 中的 Visual C++中,我們進一步移至。現在我們稽核了所有容器及其所有 Iterator,因此,多載其傳址運算子的類別必須是可以在 STL 中。
Visual Studio 2012 中的 Visual C++ C++11 超出範圍以幾種方式:
可怕 Iterator: 如允許,但不需要由標準的 C++11,可怕 Iterator 實作,如所描述 「最小化在泛型類別內的 N2911 相依性更快速且更小程式的」 和 N2980 「可怕 Iterator 指派和初始化,修正 1 "。
檔案系統:<filesystem> 標題從 TR2 提議 已加入。它提供 recursive_directory_iterator 和其他有趣的功能。在 TR2 的工作凍結之前,因為 C++0x 非常後執行而且已變更為 C++11,則 2006 年提議衍生自的。 Boost.Filesystem V2之後已變更成 Boost.Filesystem V3,,但在 Visual Studio 2012 中的 Visual C++中實作。
而主要最佳化!我們的容器現在是最佳小之所有他們目前的表示。這指的是容器物件,不對它們指向內容。例如, std::vector 會包含三個原始指標。在 Visual C++ 2010中, x86 版本的方式, std::vector 為 16 位元組。在 Visual Studio 2012 中的 Visual C++中,它是 12 個位元組,是最佳小。這很大,如果您有處理 100,000 向量在您的程式, Visual Studio 2012 中的 Visual C++ 會節省 400,000 位元組。降低記憶體使用量節省空間和時間。
這可以避免 null 配置器和比較子儲存達成,為 std::allocator ,而且 std::less 沒有狀態。(這些最佳化為自訂配置器/比較子,啟用,只要沒有狀態。很明顯地,可以設定狀態的配置器/比較子存放不能避免,不過,這些是非常罕見。)
容器大小
下表以位元組顯示容器大小,, x86 和 x64 平台的。(32 位元 ARM 與 x86 相當於這些目的)。這些桌帷發行模式,,因為偵錯模式包含檢查使用空間和階段機輸送帶連結。不同的資料列是 Visual C++ 2008 SP1 _SECURE_SCL ,預設值為 1,因此,為具有 _SECURE_SCL 的 Visual C++ 2008 SP1 手動設定 0 到最大速度的。Visual C++ 2010 和 Visual Studio 2012 中的 Visual C++ 預設 _SECURE_SCL 為 0 (現在稱為 _ITERATOR_DEBUG_LEVEL)。
x86 容器大小 (位元組) |
VC9 SP1 |
VC9 SP1 SCL=0 |
VC10 |
VC11 |
---|---|---|---|---|
向量的<int> |
24 |
16 |
16 |
12 |
<int, 5>物件的陣列。 |
20 |
20 |
20 |
20 |
雙向佇列的<int> |
32 |
32 |
24 |
20 |
<int>forward_list |
N/A |
N/A |
8 |
4 |
<int>之清單 |
28 |
12 |
12 |
8 |
<int>priority_queue |
28 |
20 |
20 |
16 |
佇列的<int> |
32 |
32 |
24 |
20 |
堆疊<int> |
32 |
32 |
24 |
20 |
<int, int>。 |
8 |
8 |
8 |
8 |
Tuple<int, int, int> |
16 |
16 |
16 |
12 |
對應<int, int> |
32 |
12 |
16 |
8 |
多重對應<int, int> |
32 |
12 |
16 |
8 |
設定<int> |
32 |
12 |
16 |
8 |
多重集<int> |
32 |
12 |
16 |
8 |
hash_map<int, int> |
72 |
44 |
44 |
32 |
<int, int>hash_multimap |
72 |
44 |
44 |
32 |
hash_set<int> |
72 |
44 |
44 |
32 |
<int>hash_multiset |
72 |
44 |
44 |
32 |
<int, int>unordered_map |
72 |
44 |
44 |
32 |
<int, int>unordered_multimap |
72 |
44 |
44 |
32 |
<int>unordered_set |
72 |
44 |
44 |
32 |
<int>unordered_multiset |
72 |
44 |
44 |
32 |
string |
28 |
28 |
28 |
24 |
wstring |
28 |
28 |
28 |
24 |
x64 容器大小 (位元組) |
VC9 SP1 |
VC9 SP1 SCL=0 |
VC10 |
VC11 |
---|---|---|---|---|
向量的<int> |
48 |
32 |
32 |
24 |
<int, 5>物件的陣列。 |
20 |
20 |
20 |
20 |
雙向佇列的<int> |
64 |
64 |
48 |
40 |
<int>forward_list |
N/A |
N/A |
16 |
8 |
<int>之清單 |
56 |
24 |
24 |
16 |
<int>priority_queue |
56 |
40 |
40 |
32 |
佇列的<int> |
64 |
64 |
48 |
40 |
堆疊<int> |
64 |
64 |
48 |
40 |
<int, int>。 |
8 |
8 |
8 |
8 |
Tuple<int, int, int> |
16 |
16 |
16 |
12 |
對應<int, int> |
64 |
24 |
32 |
16 |
多重對應<int, int> |
64 |
24 |
32 |
16 |
設定<int> |
64 |
24 |
32 |
16 |
多重集<int> |
64 |
24 |
32 |
16 |
hash_map<int, int> |
144 |
88 |
88 |
64 |
<int, int>hash_multimap |
144 |
88 |
88 |
64 |
hash_set<int> |
144 |
88 |
88 |
64 |
<int>hash_multiset |
144 |
88 |
88 |
64 |
<int, int>unordered_map |
144 |
88 |
88 |
64 |
<int, int>unordered_multimap |
144 |
88 |
88 |
64 |
<int>unordered_set |
144 |
88 |
88 |
64 |
<int>unordered_multiset |
144 |
88 |
88 |
64 |
string |
40 |
40 |
40 |
32 |
wstring |
40 |
40 |
40 |
32 |
對 Visual C++ 版本號碼的快速參考方針
Visual C++ 具有不同的版本編號會根據您所看到的地方。取得品牌版本 (列印在方塊),內部版本 (顯示在 [如需] 對話方塊) 和編譯器版本 (顯示由 cl.exe 和 _MSC_VER 巨集)。
品牌版本號碼 |
內部版本號碼 |
#define _MSC_VER 的版本號碼 |
---|---|---|
Visual C++ 2005 |
VC8 |
1400 |
Visual C++ 2008 |
VC9 |
1500 |
Visual C++ 2010 |
VC10 |
1600 |
Visual Studio 2012 中的 Visual C++ |
VC11 |
1700 |
_MSC_VER 巨集有興趣要針對 Visual C++ 不同的主要版本和發出其額外程式碼的人。