VS2010、VS2012、VS2013、VS2015對C++11的支援進度
支援 C++11/14/17 功能(現代 C++)
若要了解有關 Visual Studio 2017 RC 的最新文件,請參閱 Visual Studio 2017 RC 文件。
本文描述了 Visual C++ 中的 C++11/14/17 功能。
本文內容
Visual C++ 實現了 C++11 核心語言規範 中的絕大多數功能、許多 C++14 庫功能和某些為 C++17 建議的功能。 下表列出了 C++11/14/17 核心語言功能及其在 Visual Studio 2010、Visual Studio 2012 中的 Visual C++、Visual Studio 2013 中的 Visual C++ 和 Visual Studio 2015 中 Visual C++ 中的實現狀態。
C++11 核心語言功能表
Visual Studio 2010 | Visual Studio 2012 | Visual Studio 2013 | Visual Studio 2015 |
---|
[本文內容]
C++11 核心語言功能表:併發
C++11 核心語言功能:併發 | Visual Studio 2010 | Visual Studio 2012 | Visual Studio 2013 | Visual Studio 2015 |
---|
[本文內容]
C++11 核心語言功能:C99
C++11 核心語言功能:C99 | Visual Studio 2010 | Visual Studio 2012 | Visual Studio 2013 | Visual Studio 2015 |
---|---|---|---|---|
擴充套件的整型 | 不可用 | 不可用 | 不可用 | 不可用 |
[本文內容]
C++ 14 核心語言功能
功能 | Visual Studio 2013 | Visual Studio 2015 |
上下文轉換的已調整 workding | 是 | 是 |
二進位制文字 | 否 | 是 |
auto 和 decltype(auto) 返回型別 | 否 | 是 |
init-capture | 否 | 是 |
泛型 lambda | 否 | 是 |
變數模板 | 否 | 否 |
擴充套件的 constexpr | 否 | 否 |
聚合的 NSDMI | 否 | 否 |
避免/合成分配 | 否 | 否 |
[已棄用] 特性 | 否 | 否 |
大小經過調整的分配 | 否 | 是 |
數字分隔符 | 否 | 是 |
C++17 建議的核心語言功能
功能 | Visual Studio 2013 | Visual Studio 2015 |
針對自動使用大括號內的初始值設定項列表的新建規則 | 否 | 否 |
簡要靜態斷言 | 否 | 否 |
模板-引數模板的型別名稱 | 否 | 否 |
刪除三字元組 | 是 | 是 |
巢狀的名稱空間定義 | 否 | 否 |
N4259 std::uncaught_exceptions() | 否 | 否 |
N4261 修復限定轉換 | 否 | 否 |
N4266 名稱空間和列舉器的特性 | 否 | 否 |
N4267 u8 字元文字 | 否 | 否 |
N4268 允許更多非型別模板引數 | 否 | 否 |
N4295 Fold 摺疊表示式 | 否 | 否 |
等待/繼續 | 否 | 是 |
功能表指南
右值引用
說明 |
---|
以下描述中的版本識別符號(v0.1、v1.0、v2.0、v2.1、v3.0)僅用來演示 C++11 的發展。 標準本身不會使用它們。 |
N1610“通過右值澄清類物件的初始化”是早期在不引用右值的情況下支援移動語義的一種嘗試。 為方便討論,我們稱之為“右值引用 0.1 版”。 它由“右值引用 v1.0”取代。
“右值引用 v2.0”是 Visual Studio 2010 中的 Visual C++ 功能的基礎,它禁止將右值引用繫結到左值,因此可以解決主要的安全性問題。 “右值引用 v2.1”重新定義了此規則。
讓我們看一下 vector<string>::push_back()
,它具有過載 push_back(const
string&)
和 push_back(string&&)
以及呼叫 v.push_back("strval")
。
表示式 "strval"
是字串,並且是左值。 (其他文字為右值,如整數 1729,但字串有些特殊,因為它們是陣列。) “右值引用 2.0 版”規則顯示,string&&
無法繫結到 "strval"
,因為 "strval"
是左值,因此 push_back(const
string&)
是唯一可行的過載。 這將建立一個臨時 std::string
,並將它複製到向量中,然後銷燬效率不太高的臨時 std::string
。
“右值引用 2.1 版”規則確認,將 string&&
繫結到 "strval"
將建立臨時 std::string
,並且該臨時字串為右值。
因此,push_back(const string&)
和 push_back(string&&)
都是可行的,但首選 push_back(string&&)
。
將構造一個臨時 std::string
,然後將它移至向量中。 這樣效率更高。
“右值引用 v3.0”將新增新規則,以在特定條件下自動生成移動建構函式和移動賦值運算子。 這是在 Visual Studio 2015 中實現的。
[本文內容]
Lambdas
在 lambda 函式選入到工作檔案(“0.9”版)並且已新增可變的
lambda(“1.0”版)之後,標準化委員會全面修訂了措詞。 這產生了 lambda“1.1”版,這個版本現在已完全受支援。
lambda 1.1 版的措詞闡明瞭在特殊案例(例如引用靜態成員或巢狀 lambda)中會發生的情況。 這將修復由複雜 lambda 觸發的問題。 此外,無狀態的 lambda 現在可轉換為函式指標。 這沒有包含在 N2927 措詞中,但是無論如何都會將它計作 lambda 1.1 版的一部分。C++11 5.1.2
[expr.prim.lambda]/6 具有以下說明:“無 lambda-capture
的 lambda-expression
的閉包型別使用一個公共的非虛擬、非顯式常量轉換函式指向一個具有與閉包型別的函式呼叫運算子相同的引數和返回型別的函式。
此轉換函式返回的值應為一個函式的地址,呼叫該函式時,其效果和呼叫閉包型別的函式呼叫運算子相同。” (Visual Studio 2012 中的 Visual C++ 實現的效果甚至更好,因為它使無狀態的 lambda 可轉換為具有任意呼叫約定的函式指標。 當你在使用期待像 __stdcall
函式指標這類物件的
API 時,這點很重要。)
[本文內容]
decltype
在 decltype 選入到工作檔案(1.0 版)後,在最後時刻收到了一個小的但很重要的修復(1.1 版)。 這對從事 STL 和 Boost 工作的程式設計師很有好處。
[本文內容]
強型別/前向宣告列舉
Visual Studio 2010 中的 Visual C++ 部分支援 強型別的列舉(具體而言,支援有關顯式指定的基礎型別部分)。 現在這些在 Visual Studio 中已完全實現,前向宣告列舉的 C++11 語義也已完全實現。
[本文內容]
對齊方式
選入工作檔案的對齊方式提案中的核心語言關鍵字 alignas
/alignof
在
Visual Studio 2015 中已實現。 Visual Studio 2010 中的 Visual C++ 具有來自 TR1 的 aligned_storage
。Visual
Studio 2012 中的 Visual C++ 已將 aligned_union
和 std::align()
新增到標準庫,而且重大的問題已在
Visual Studio 2013 中的 Visual C++ 中修復。
[本文內容]
標準佈局和普通型別
來自 N2342“POD 重新訪問;解決核心問題 568(修訂 5)”的公開更改是將 is_trivial
和 is_standard_layout
新增到標準模板庫的 <type_traits>
。
(N2342 修改了大量核心語言措詞,但無需進行編譯器更改。) 這些型別特徵在 Visual Studio 2010 的 Visual C++ 中已提供,但它們只是複製了 is_pod
。
因此,本文件中之前的表顯示“不支援”。 它們現在由設計用於給出精確答案的編譯器掛鉤驅動。
STL 的 common_type 在 Visual Studio 2013 中的 Visual C++ 中得到了迫切需要的修復。common_type<>
的
C++11 規範導致意外後果;具體而言,它使 common_type<int, int>::type
返回 int&&
。
因此,Visual Studio 2013 中的 Visual C++ 可實現建議用於庫工作組問題 2141 的解決方法,使 common_type<int,
int>::type
返回 int
。
作為此更改的副作用,標識用例不再起作用(common_type<T>
並不總是產生 T
型別)。
這將遵循建議的解決方法,但其將中斷依賴於先前行為的所有程式碼。
如果需要標識型別特徵,請不要使用 std::identity
中定義的非標準 <type_traits>
,因為它對 <void>
無效。
相反,實現你自己的標識型別特徵以滿足你的需求。 以下是一個示例:
template <typename T> struct Identity { typedef T type; };
[本文內容]
預設函式和已刪除的函式
這些函式現在均受支援,但此種情況例外:對於預設函式,不支援使用 =default
請求識別成員的移動建構函式和移動賦值運算子。 複製和移動操作並不按照標準規定的方式進行精確互動
- 例如,指定刪除移動會同時禁止顯示覆制操作,但 Visual Studio 2013 中的 Visual C++ 不會。
有關如何使用預設函式和已刪除的函式的資訊,請參閱函式。
[本文內容]
override 和 final
這經歷了短暫而複雜的發展。 最初,在 0.8 版中,具有 [[override
]]、[[hiding
]]
和 [[base_check
]] 特性。 然後在 0.9
版中,消除了這些特性並將其替換為上下文關鍵字。 最後,在 <