cpp c++ 11/14/17

我們常用的c++,你對它的標準瞭解多少呢?本文就帶你一探c++11新標準。官網鏈接:https://msdn.microsoft.com/zh-cn/library/hh567368.aspx#featurelist

 

C++11 功能列表

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 核心語言功能表

C++11 核心語言功能 Visual Studio 2010 Visual Studio 2012 Visual Studio 2013 Visual Studio 2015
右值引用 v0.1v1.0v2.0v2.1v3.0 2.0 版 2.1* 版 2.1* 版 v3.0
引用限定符
非靜態數據成員初始值設定項
可變參數模板 v0.9v1.0
初始值設定項列表
static_assert
auto v0.9v1.0 v1.0 v1.0 v1.0
結尾返回類型
Lambdas v0.9v1.0v1.1 v1.0 v1.1 v1.1
decltype v1.0v1.1 v1.0 v1.1** v1.1
右尖括號
函數模板的默認模板參數
表達式 SFINAE
別名模板
Extern 模板
nullptr
強類型的枚舉 部分
前向聲明枚舉
特性
constexpr
對齊方式 TR1 部分 部分
委託構造函數
繼承構造函數
顯式轉換運算符
char16_t/char32_t
Unicode 字符串文本
原始字符串文本
文本中的通用字符名
用戶定義的文本
標準佈局和普通類型
默認函數和已刪除的函數 是*
擴展的友元聲明
擴展的 sizeof
內聯命名空間
無限制的聯合
作爲模板參數的本地和未命名類型
基於範圍的 for 循環
override 和 final v0.8v0.9v1.0 部分
最低 GC 支持
noexcept

[本文內容]

C++11 核心語言功能表:併發

C++11 核心語言功能:併發 Visual Studio 2010 Visual Studio 2012 Visual Studio 2013 Visual Studio 2015
改寫的序列點 不可用 不可用 不可用
原子
強比較和交換
雙向界定
內存模型 不可用 不可用 不可用
數據依賴項排序
數據依賴項排序:函數批註
exception_ptr
quick_exit
信號處理程序中的原子化
線程本地存儲區 部分 部分 部分
神奇的靜態對象

[本文內容]

C++11 核心語言功能:C99

C++11 核心語言功能:C99 Visual Studio 2010 Visual Studio 2012 Visual Studio 2013 Visual Studio 2015
__func__ 部分 部分 部分
C99 預處理器 部分 部分 部分 部分
long long
擴展的整型 不可用 不可用 不可用 不可用

[本文內容]

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 摺疊表達式
等待/繼續

 

功能表指南

右值引用

System_CAPS_ICON_note.jpg 說明

以下描述中的版本標識符(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> 無效。 相反,實現你自己的標識類型特徵以滿足你的需求。 以下是一個示例:

C++

template <typename T> struct Identity { typedef T type; };  
  

System_CAPS_ICON_note.jpg 說明

有關其他重大更改,請參閱Visual C++ 2015 中的重大更改

[本文內容]

默認函數和已刪除的函數

這些函數現在均受支持,但此種情況例外:對於默認函數,不支持使用 =default 請求識別成員的移動構造函數和移動賦值運算符。 複製和移動操作並不按照標準規定的方式進行精確交互 - 例如,指定刪除移動會同時禁止顯示覆制操作,但 Visual Studio 2013 中的 Visual C++ 不會。

有關如何使用默認函數和已刪除的函數的信息,請參閱函數

[本文內容]

override 和 final

這經歷了短暫而複雜的發展。 最初,在 0.8 版中,具有 [[override]]、[[hiding]] 和 [[base_check]] 特性。 然後在 0.9 版中,消除了這些特性並將其替換爲上下文關鍵字。 最後,在 1.0 版中,將它們精簡爲類的“final”以及函數的“override”和“final”。 這使它成爲一個獲得提升的擴展,因爲 Visual Studio 2010 中的 Visual C++ 已支持對函數使用此“override”語法,並且語義相當接近於 C++11 中的語義。 “final”也受支持,但拼寫不同(“sealed”)。 現在完全支持“override”和“final”的標準拼寫和語義。 有關詳細信息,請參閱 override 說明符 和 final 說明符

[本文內容]

原子化及更多信息

原子化強比較和交換雙向界定數據依賴項排序指定現在已實現的標準庫機制。

相關 STL 標頭: <atomic><chrono><condition_variable><future><mutex><ratio><scoped_allocator> 和 <thread>

[本文內容]

C99 __func__ 和預處理器規則

C++11 核心語言功能:C99 表列出了兩個項的“部分”實現。 對於預定義標識符 __func__,列出“分部”,因爲對非標準擴展 __FUNCDNAME____FUNCSIG__ 和 __FUNCTION__ 提供了支持。 有關詳細信息,請參閱 預定義的宏。 對於 C99 預處理器規則,列出“分部”,因爲支持可變參數宏。 有關詳細信息,請參閱 Variadic 宏

[本文內容]

標準庫功能

這涵蓋核心語言。 至於 C++11 標準庫,我們雖沒有漂亮的功能比較表,但 Visual Studio 2012 中的 Visual C++ 已實現此功能,但具有兩個例外。 首先,當某個庫功能依賴於編譯器中缺少的功能時,該功能要麼是模擬的(例如,make_shared<T>() 的模擬可變參數模板),要麼沒有實現。 (僅有少數情況現在已經在 Visual Studio 2013 中的 Visual C++ 中完全實現,其中最值得注意的是 <initializer_list>。) C99 已在 Visual Studio 2013 中的 Visual C++ 和提供的 C++ 包裝器標頭中實現,並且例外情況非常少。 有關更多信息,請參閱 Visual Studio 2013 中的 C99 庫支持

下面列出了 Visual Studio 2012 中的 Visual C++ 和 Visual Studio 2013 中的 Visual C++ 中的部分更改:

定位:根據 C++11 的要求,emplace()/emplace_front()/emplace_back()/emplace_hint()/emplace_after() 已在所有包含“任意”數量參數的容器中實現(請參見“模擬的可變參數”部分)。 例如,vector<T> 具有“template <typename... Args> void emplace_back(Args&&... args)”(它在向量的後面從任意數量的任意參數時直接構造元素類型 T,這稱爲“完全轉發”)。 這相對於 push_back(T&&)(將涉及額外的移動構造和析構)效率更高。

可變參數: Visual Studio 2012 中的 Visual C++ 具有用於模擬可變參數模板的方案。 在 Visual Studio 2013 中的 Visual C++ 中,取消了模擬,並完全實現了可變參數。 如果你的代碼依賴舊的模擬可變參數行爲,則必須修復它。 但是,切換到實際可變參數模板增加了編譯次數,並降低了編譯器的內存消耗

顯式轉換運算符:在覈心語言中,顯式轉換運算符是一項常規功能 — 例如,你可以具有 explicit operator MyClass()。 但是,標準庫當前僅使用一種形式:explicit operator bool(),這使類成爲安全的布爾值可測試的類。 (無格式“operator bool()”是非常危險的。) 過去,Visual C++ 模擬了帶有 explicit operator bool() 的 operator pointer-to-member(),這導致各種問題,並且效率有些低下。 現在,完全移除了此“虛擬 bool”工作區。

隨機性: uniform_int_distribution 現在是完全公平的,並且在 <algorithm> 中實現了 shuffle(),這樣便可以直接接受統一隨機數生成器,如 mersenne_twister

防止重載 address-of 運算符:C++98/03 禁止 STL 容器的元素重載其 address-of 運算符。 這是類似 CComPtr 的類完成的操作,因此使 STL 避免此類重載需要類似 CAdapt 的幫助程序類。 開發 Visual Studio 2010 中的 Visual C++ 時,STL 更改使其在更多情況下拒絕重載 address-of 運算符。 C++11 更改了相關要求,使得重載 address-of 運算符可接受。 Visual Studio 2010 中的 C++11 和 Visual C++ 提供幫助程序函數 std::addressof(),此函數可獲取對象的真實地址(無論運算符是否重載)。 在發佈 Visual Studio 2010 中的 Visual C++ 之前,我們已嘗試將“&elem”的匹配項替換爲具有一定抵抗性的“std::addressof(elem)”。Visual Studio 2012 中的 Visual C++ 更進一步,這樣重載 address-of 運算符的類就能在整個 STL 中使用了。

Visual Studio 2012 中的 Visual C++ 在下列方面超出了 C++11 的範圍:

SCARY 迭代器:實現了 SCARY 迭代器,如 N2911“在泛型類中最小化依賴項以獲得更快且更小的程序”和 N2980“SCARY 迭代器分配和安裝,第一版”中所述,這在 C++11 標準是允許的,但不是必需的。

文件系統:已添加 TR2 建議中的 <filesystem> 標頭。 它提供 recursive_directory_iterator 和其他有趣功能。 在 TR2 的工作凍結之前,由於 C++0x 很晚才投入運行且將更改爲 C++11,因此從 Boost.Filesystem V2 派生出了 2006 協議。 它稍後改進爲 Boost.Filesystem V3,這在 Visual Studio 2015 中實現。

一個主要優化! 現在,我們的所有容器相對於當前的表示形式都具有最小的合適大小。 這指的是容器對象本身,而不是它們指向的內容。 例如,std::vector 包含三個原始指針。 在 Visual Studio 2010 中的 Visual C++ 中,x86 發佈模式 std::vector 爲 16 字節。 在 Visual Studio 2012 中的 Visual C++ 中,它爲 12 字節,這是最小的合適大小。 如果你的程序有 100,000 個向量,則 Visual Studio 2012 中的 Visual C++ 將爲你節省 400,000 字節,這很了不起。 減少內存使用率可節省空間和時間。

這是通過避免存儲空的分配器和比較運算符來實現的,因爲 std::allocator 和 std::less 是無狀態的。 (只要自定義分配器/比較運算符是無狀態的,也會爲它們啓用這些優化。 顯然,無法避免有狀態的分配器/比較運算符的存儲,但這種情況極爲少見。)

Visual Studio 2013 中的 Visual C++ 實現一些關鍵的 C++ 14 庫功能:

  • “透明運算符函子”less<>greater<>plus<>multiplies<> 等。

  • make_unique<T>(args...) 和 make_unique<T[]>(n)

  • cbegin()/cend()rbegin()/rend() 和 crbegin()/crend() 非成員函數

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章