1. 程式人生 > >C++17 相比於 C++14 的所有重大變化

C++17 相比於 C++14 的所有重大變化

摘要

本文件列舉了自C++14釋出以來,到C++17 DIS(N4660)釋出為止,應用於C++工作草案(working draft)的所有重大變化。重大變化(major changes)是以專門的檔案(paper)的形式加入的。不是每個檔案都單獨在此提及,沒有單獨提及的檔案在下面簡要列出。CWG或LWG問題清單(issue list)中的問題解決方案(issue resolution)通常不包括在重大變化之內,但是包含問題解決方案的檔案也會簡要列出。

目錄

  1. 刪除或棄用的特性
  2. 具有全域性影響的新的核心語言特性
  3. 具有區域性影響的新的核心語言特性
  4. 新的庫特性
  5. 對現有特性的修改
  6. 雜項
  7. 未列入的檔案
  8. 展示C++17的程式碼片段合集

刪除或棄用的特性

檔案:N4086
概要:刪除trigraph
註釋:字元序列 ??! 不再表示 | 。實現(implementation)可以把類似trigraph的功能作為輸入編碼的一環。

檔案:P0001R1
概要:刪除register
註釋:register仍然是保留字,但是不再具有任何語義。

檔案:P0002R1
概要:刪除bool型別的++運算
註釋:前自增和後自增運算子不再接受bool型別的運算元。

檔案:P0003R5
概要:刪除throw(A, B, C)
註釋:形如throw(A, B, C)的動態異常規範(dynamic exception specification)不再是合法的。throw()保留,成為noexcept(true)的同義詞。注意throw()的語義變化。

檔案:P0386R2
概要:棄用static constexpr成員的重複宣告
註釋: 對於struct X { static constexpr int n = 10; };,int X::n;不再是定義,而是多餘的重複宣告,這種重複宣告已被棄用。成員X::n是隱含的inline變數(見下文)。

———-

檔案:N4190
概要:刪除auto_ptr、random_shuffle、<functional>中的過時部分
註釋:在C++11已經被棄用並被更好的元件取代的功能將不再包含於C++17中。它們的名字仍然是保留的,實現可以選擇繼續提供。

檔案:P0004R1
概要:刪除被棄用的iostream成員
註釋:同上

檔案:P0302R1
概要:刪除std::function的記憶體分配器(allocator)支援
註釋:多型函式包裝器function不再具有接受記憶體分配器的建構函式。記憶體分配器支援對具有型別擦除(type-erase)功能的可複製型別來說很困難,可能無法有效實現。

檔案:P0063R3(見下文)
概要:棄用一些C庫(C library)標頭檔案(header)
註釋:“C庫”(C library,這個術語指的是C++標準庫的一部分, 而不是C標準庫的一部分)中的以下標頭檔案被棄用:<ccomplex>、<cstdalign>、<cstdbool>、<ctgmath>。注意<ciso646>標頭檔案沒有被棄用。

檔案:P0174R2
概要:棄用標準庫中的陳舊部分
註釋:以下元件被棄用:allocator<void>、raw_storage_iterator、get_temporary_buffer、is_literal_type、std::iterator。

檔案:P0618R0
概要:棄用<codecvt>
註釋:整個<codecvt>標頭檔案(注意codecvt類並不在這個標頭檔案中)被棄用。wstring_convert和wbuffer_convert也被棄用。這些功能難以正確使用,甚至有懷疑它們的規範是否正確。使用者應該使用專用的文字處理庫。

檔案:P0371R1
概要:暫時棄用memory_order_consume
註釋: 當前的“consume”記憶體序的語義被發現是不夠的,需要重新定義。這項工作希望能在C++的下一版中完成。在進行這項工作的時間裡,建議使用者不要使用“consume”記憶體序,而是使用“acquire”記憶體序,以免將來遇到問題。

檔案:P0521R0
概要:棄用shared_ptr::unique
註釋:該成員函式暗示了沒有實際提供的行為。

檔案:P0604R0
概要:棄用result_of
註釋:請改用新的trait:invoke_result。

具有全域性影響的新的核心語言特性

這些是在不需要你知情或同意的情況下,你可能遇到的特性。

檔案:P0012R1
概要:異常規範(exception specification)作為型別系統的一部分
註釋:函式的異常規範現在是函式型別的一部分:void f() noexcept(true); 和 void f() noexcept(false); 是具有不同型別的函式。函式指標可以按符合常理的方式轉換。(但是這兩個函式 f 不能構成過載。)這個變化加強了型別系統。例如,API可以通過型別系統要求回撥函式不丟擲異常。

檔案:P0135R1
概要:保證的複製消除(guaranteed copy elision)
註釋:prvalue和glvalue的含義已被修改,prvalue不再代表物件(object),而僅僅代表“初始化”(“initialization”)。返回prvalue的函式不再會複製物件(強制複製消除“mandatory copy elision”),並且有了新的從prvalue到glvalue的轉換,叫做temporary materialization conversion。這個變化意味著複製消除是保證了的,而且甚至可以應用於不可移動或複製的型別。這允許你定義返回這種(不可移動或複製的)型別的函式。

檔案:P0035R4
概要:過度對齊型別(over-aligned types——即alignment超過std::max_align_t的型別)的動態記憶體分配
註釋:動態記憶體分配(operator new)現在可以支援過度對齊的型別,這個運算子的一個新的過載接受對齊要求(alignment)引數。仍然是由實現決定支援哪些對齊。

檔案:P0145R3
概要:更嚴格的表示式求值順序
註釋:對某些子表示式的求值順序的規定更多了。這個變化的一個重要方面是函式的各個實參現在以不確定(indeterminate)的順序的求值(也就是說沒有交錯 interleaving),而以前只是未指定的(unspecified)。注意過載運算子的求值順序和呼叫方式有關:如果按照運算子的形式呼叫,就和相應的內建運算子的順序相同;如果按照函式呼叫的形式呼叫,就和一般的函式呼叫相同(也就是不確定的 indeterminate)。

具有區域性影響的新的核心語言特性

這些是如果你要使用,你就需要知道的特性。

檔案:N4267
概要:u8字元字面量
註釋:具有u8字首的字元字面量產生一個在UTF-8中佔有一個編碼單元(code unit)的合法Unicode程式碼點(code point)對應的字元,換句話說,就是產生一個ASCII值。例如:u8’x’。

檔案:P0245R1
概要:十六進位制浮點數字面量
註釋:具有十六進位制底數和十進位制指數的浮點數字面量: 0xC.68p+2, 0x1.P-126。C語言自從C99開始就支援這種語法, printf的%a可以輸出這種形式的浮點數。

檔案:N4295, P0036R0
概要:fold表示式
註釋:用於迭代地將二元運算子應用於引數包(parameter pack)的元素的便利語法:template <typename …Args> auto f(Args …args) { return (0 + … + args); }

檔案:P0127R2
概要:template <auto>
註釋:模板的非型別形參可以用佔位符型別auto宣告。例如:
• template <auto X> struct constant { static constexpr auto value = X; };
• Delegate<&MyClass::some_function>
(←_←第二個例子的完整版本見下文)

檔案:P0091R3, P0512R0, P0433R2, P0620R0
概要:類模板引數推導
註釋:類模板的模板引數現在可以從建構函式推導。例如 pair p(1, ‘x’); 定義 p 為 pair<int, char> 型別的變數(這不是HTML錯誤,模板實參是故意省略的)。顯式的推導指引(deduction guide)是隱式推導的補充,顯式的推導指引允許作者定製推導如何發生,或者禁止推導。

檔案:P0292R2
概要:Constexpr if
註釋:新的 if constexpr (condition) 語句根據常量表達式(constant expression)的值選擇執行哪個分支。在模板的例項中,只有在條件(condition)具有合適的值的時候,對應的分支才會例項化。

檔案:P0305R1
概要:帶初始化的選擇語句
註釋:選擇語句 if 和 switch 有了一個新的、可選的初始化部分:if (auto it = m.find(key); it != m.end()) return it->second;

檔案:P0170R1
概要:Constexpr lambda
註釋:lambda表示式現在可以是常量表達式了:auto add = [](int a, int b) constexpr { return a + b; }; int arr[add(1, 2)];

檔案:P0018R3
概要:lambda捕獲*this
註釋:以前:[self = *this]{ self.f(); } 現在:[*this]{ f(); }

檔案:P0386R2, P0607R0
概要:inline變數
註釋:在標頭檔案中:inline int n = 10; 所有定義都指代同一個實體。static constexpr 成員變數隱含地成為 inline 變數。(標準庫中的常量,不論是已有的還是新增的,都已使用inline。)

檔案:P0217R3, P0615R0
概要:結構化繫結
註釋:auto [it, ins] = m.try_emplace(key, a1, a2, a3);
可以分解陣列、所有成員都是public的類、像pair、tuple和array一樣遵循get<N>協議的自定義型別。

檔案:P0061R1
概要:__has_include
註釋:檢查能否包含特定標頭檔案的預處理運算子。

檔案:P0188R1 P0189R1 P0212R1
概要:屬性(attribute)[[fallthrough]]、[[nodiscard]]、[[maybe_unused]](分別對應三個檔案)
註釋:一套新的標準化屬性。屬性沒有必要的語義,但是鼓勵實現發出或抑制適當的診斷(警告)。

檔案:P0137R1
概要:launder
註釋:語言支援工具(“優化屏障optimisation barrier”),允許庫重新使用儲存(storage),並通過舊指標訪問該儲存(以前是不允許的)。(這是實現者的專家工具,預期不會在“正常”程式碼中出現)。

檔案:P0298R3
概要:位元組型別
註釋:新的型別byte在<cstddef>中定義(不在<stddef.h>,並且只定義在名稱空間std中),它和unsigned char具有相同的佈局,和現有的字元型別一樣允許別名(aliasing),並且定義了按位操作。

新的庫特性

檔案:P0226R1
概要:數學特殊函式(mathematical special functions)
註釋:前國際標準ISO/IEC 29124:2010(數學特殊函式)的內容現在是C++的一部分。 這些函式只新增到<cmath> ,而沒有新增到<math.h> ,並且只定義在名稱空間std中。

檔案:P0218R0, P0219R1, P0317R1, P0392R0, P0430R2, P0492R2
概要:檔案系統
註釋:檔案系統技術規範(Filesystems Technical Specification)的內容現在是C++的一部分。 檔案系統庫允許以可移植的方式與目錄和類似目錄的結構進行互動(列出檔案目錄的內容,移動檔案等)。 它主要以POSIX為模型,但它足夠靈活,可以在各種系統上實現。

檔案:P0024R2, P0336R1, P0394R4, P0452R1, P0467R2, P0502R0, P0518R1, P0523R1, P0574R1, P0623R0
概要:並行
註釋:並行技術規範(Parallelism Technical Specification)的內容現在是C++的一部分。它為很多演算法(algorithm)增加了過載,這些新的過載額外接受一個執行策略execution policy)引數。它也加入了新的演算法(見下文)。 支援三種執行策略,分別提供順序(sequential),並行( parallel)和向量化(vectorized)的執行。

檔案:P0024R2
概要:新演算法
註釋:並行技術規範為標準庫添加了幾種新演算法。加入它們的動機是它們可以有效地並行執行,但也提供了通常的(不接受execution policy引數的)簡單形式:for_each_n、reduce、transform_reduce、exclusive_scan、inclusive_scan、transform_exclusive_scan、transform_inclusive_scan。請注意, reduce看起來與現有的accumulate相似,但reduce不保證任何特定的操作順序。

檔案:P0220R1, P0254R2, P0403R1
概要:新型別:string_view(以及basic_string_view)
註釋:新的string_view類是API介面的推薦型別,如果API需要讀取字串的內容,但是不需要取得字串的所有權或者修改字串。它可以從char指標構造,但是其他的字串型別應該自己提供到string_view的隱式轉換。

檔案:P0220R1, P0032R3, P0504R0
概要:新型別:any
註釋:型別any對可複製(copyable)的物件進行型別擦除(type-erase)。基本上可以用any做以下三件事:1. 把T型別的值放入其中。2. 複製它。 3. 檢查它是否包含一個U型別的值,並且取出這個值,取出操作只有在U就是T的時候才會成功。

檔案:P0088R3, P0393R3, P0032R3, P0504R0, P0510R0
概要:新的類模板:variant
註釋:variant是一個可辨識聯合(disjoint union / discriminated union)。variant<A, B, C> 型別的值在任何時間都包含一個型別為A、B或C之一的值。

檔案:P0220R1, P0307R2, P0032R3, P0504R0
概要:新的類模板:optional
註釋:一個可選的值。一個optional<T>表示一個T值,或者表示沒有值(由型別nullopt_t標記)。在某些方面,可以認為它等同於variant<nullopt_t, T>,但是它具有專門的介面。

檔案:P0220R1
概要:新演算法:sample
註釋:從一個範圍(range)裡均勻選取最多n個元素作為樣本。

檔案:N4169
概要:invoke
註釋:以統一形式呼叫Callable實體(包括函式、函式物件和成員指標)的工具。這允許使用者編寫的庫可以使用與標準的魔法(magic)INVOKE規則相同的行為。

檔案:P0077R2, P0604R0
概要:is_invocable, is_invocable_r, invoke_result
註釋:用於推斷可呼叫性和呼叫結果的trait。(←_←看名字就知道應該和std::invoke配合使用。C++11的result_of也應該和invoke配合使用來著,如果只支援函式和函式物件應該直接用decltype,可惜名字取得不好,造成不少誤用)

檔案:P0067R5
概要:基本字串轉換
註釋:函式to_chars和from_chars分別生成和解析數字的字串表示。這些旨在形成用於替換printf和iostream格式化操作的高效、低階(low-level)的基礎。它們遵循慣用的C++演算法風格。

檔案:N3911
概要:類型別名模板void_t
註釋:template <class…> using void_t = void; 在超程式設計中驚人地有用,簡化了SFINAE的使用。

檔案:N4389
概要:類型別名模板bool_constant
註釋:template <bool B> using bool_constant = integral_constant<bool, B>

檔案:P0013R1
概要:邏輯操作元函式
註釋:用於超程式設計的變長元函式conjunction、disjunction和negation。這些trait在超程式設計的意義上是短路(short-circuit)的:不影響結果的模板不會被例項化。

檔案:P0185R1
概要:用於SFINAE友好(SFINAE-friendly)swap的traits
註釋:新的trait is_swappable、is_nothrow_swappable、is_swappable_with、is_nothrow_swappable_with。

檔案:LWG 2911
概要:Trait is_aggregate
註釋:檢查型別是否是聚合類(aggregate)。例如,可以用於判斷泛型型別(←_←就是作為模板引數的型別)是應該用列表初始化(list-initialization)還是應該用非列表初始化(non-list-initialization)。

檔案:P0258R2
概要:Trait has_unique_object_representations
註釋:這個trait可以用來判斷特定的基於值的操作(例如比較和求hash值)是否可以用基於物件表示(object representation)的操作(例如memcmp)代替。

檔案:P0007R1
概要:as_const
註釋:給定lvalue x,std::as_const(x)返回相應的帶const限定符的lvalue。std::as_const不能接受rvalue。

檔案:N4280
概要:非成員函式size、data、empty
註釋:新增的函式補充了現有的非成員函式begin、end等等。通過這些函式,可以用統一的方式訪問標準容器和C風格陣列。注意,和begin/end不同,這些新的函式不是定製點(customisation point),僅為方便起見提供。(←_←不知道原文作者為什麼強調 the new functions are not customisation points,記得customization point是Ranges裡的術語,而且在Ranges裡這些非成員函式確實是customization point object)

檔案:P0025R0
概要:clamp
註釋:clamp(x, low, high)在x處於區間[low, high]內時返回x,否則返回最接近的邊界(小於low就返回low,大於high就返回high)。

檔案:P0295R0
概要:gcd和lcm
註釋:數論中的函式,計算兩個整數的最大公約數和最小公倍數。

檔案:N4508
概要:shared_mutex類
註釋:讀-寫互斥體,能夠以共享或獨佔模式鎖定。

檔案:P0154R1
概要:干擾尺寸(interference sizes)
註釋:兩個新的實現定義常量hardware_constructive_interference_size、hardware_destructive_interference_size允許平臺記錄其快取記憶體行大小(cache line size),以便使用者避免虛假共享(破壞性干擾)並提高區域性性(建設性干擾)。定義了兩個單獨的常量,以支援異構體系結構(heterogeneous architecture)。

檔案:P0220R1
概要:元組(tuple)apply
註釋:呼叫一個callable,引數從給定的元組中提取。

檔案:P0209R2
概要:從元組構造
註釋:新的函式模板make_from_tuple,功能是用給定元組的成員初始化T型別的值。它有點像剛提到的apply,但是它用於建構函式。

檔案:P0005R4, P0358R1
概要:通用否定函式物件not_fn
註釋:一個呼叫包裝器(call wrapper),對它包裝的callable取否定。它適用於具有任意數量引數的callable。它取代了舊的not1和not2包裝器。

檔案:P0220R1
概要:memory resource
註釋:一套新的元件,包括用於動態選擇記憶體提供者的memory resource基類,以及三個具體實現(synchronized_pool_resource、unsynchronized_pool_resource、monotonic_buffer_resource)。有關用例參見下一條。

檔案:P0220R1, P0337R0
概要:多型的記憶體分配器
註釋:使用memory resource的記憶體分配器,memory resource可以在執行時改變,不是分配器型別的一部分。為方便使用,還提供了類型別名,如std::pmr::vector<T> = std::vector<T, polymorphic_allocator<T>>。

檔案:P0220R1, P0253R1
概要:搜尋器函式物件
註釋:使用Boyer-Moore和Boyer-Moore-Horspool演算法、用於搜尋子字串的函式物件,和一個使用這些函式物件的algorithm。

對現有特性的修改

檔案:N3928
概要:只接受一個引數的static_assert
註釋:static_assert宣告不再需要第二個引數:static_assert(N > 0);

檔案:N4230
概要:巢狀名稱空間宣告
註釋:namespace foo::bar { /* … */ }

檔案:N4051
概要:允許用typename宣告模板的模板引數(template template parameters)
註釋:template <template <typename> typename Tmpl> struct X; 以前,模板的模板引數的宣告只能用關鍵字class。

檔案:P0184R0
概要:基於範圍的for迴圈(range-based for)接受不同的begin/end型別
註釋:for (decl : expr) 的規則受到重寫,從以前的auto __begin = begin-expr, __end = end-expr;改成現在使用的 auto __begin = begin-expr; auto __end = end-expr;。這使得基於範圍的for迴圈為新的Ranges(工作正在進行中)做好準備。

檔案: P0195R2
概要:using-declaration 中的包擴充套件(pack expansion)
註釋:template <typename …Args> struct X : Args… { using Args::f…; };

檔案:P0138R2
概要:固定列舉(fixed enum)值的構造
註釋:型別為固定列舉 E 的變數可以用 E e { 5 }; 的形式定義,不再需要更囉嗦的 E e { E(5) };。

檔案:N3922
概要:從花括號列表中推導auto的新規則
註釋:以前,auto a{1, 2, 3}, b{1}; 是允許的,兩個變數的型別都是 initializer_list<int>。現在 auto a{1, 2, 3}; 是錯誤的(ill-formed), auto b{1}; 宣告一個 int。注意,auto a = {1, 2, 3}, b = {1}; 保持不變,推匯出 initializer_list<int> 。此改變預期作為缺陷解決方案(defect resolution)(在C++11和C++14模式下也會使用新規則)。

檔案:N4259
概要:uncaught_exceptions()
註釋:函式uncaught_exception被棄用,新函式uncaught_exceptions返回計數而不是布林值。以前的功能實際上是不能用的,N4152解釋了細節。

檔案:N4266
概要:名稱空間(namespace)和列舉成員(enumerators)的屬性(attributes)
註釋:名稱空間和列舉成員現在可以用屬性標記。例如,這允許標記名稱空間和列舉成員為棄用的(deprecated)。

檔案:P0028R4
概要:屬性名稱空間(attribute namespace)不需要重複指定
註釋:當重複使用某一個屬性名稱空間時,這簡化了名稱空間限定。

———-

檔案:N4279
概要:改進了std::map和std::unordered_map的插入
註釋:m.try_emplace(key, arg1, arg2, arg3) 在m中已經含有key的時候沒有任何效果,否則插入一個從引數構造的新元素。這個介面(interface)保證即使實參繫結到右值引用(rvalue reference),如果沒有發生插入,實參將不會被移動(not moved from)。

檔案:P0084R2
概要:emplace的返回型別
註釋:順序容器(sequence container)的過去返回void的emplace、emplace_front、emplace_back成員函式模板,現在返回剛剛插入的元素的引用。(關聯容器不受影響,因為它們的插入函式一直都返回相關元素的迭代器。)

檔案: P0083R3, P0508R0
概要:set和map的拼接(splice)
註釋:一個叫做節點控制代碼node handle)的新機制加入了標準容器庫。這個新機制允許在不同的map/set物件之間移植元素,而不會觸及容器中的物件。此外,這個機制使得對提取(extract)出的鍵值進行可變訪問成為可能。(←_←可以不使用mutable就修改set的元素和map的key了,當然在修改之前必須先提取出來,修改之後再插入回去,以保證set和map的內部結構不受破壞)

檔案:P0272R1
概要:非const的string::data
註釋:現在有了一個非const的basic_string::data過載,返回一個可變的(mutable)指標。此外,C++17允許向空終止符(null terminator)寫入,只要寫入的值是零。這使得字串類更便於和C風格介面一起使用。

檔案:P0156R0, P0156R2
概要:變長(variadic)版的lock_guard,名叫scoped_lock
註釋:增加了變長的類模板scoped_lock<Args…>。它可以同時給多個可鎖的物件(lockable object)加鎖(使用和std::lock相同的演算法),並且在解構函式中釋放鎖。一開始建議直接修改lock_guard,使它成為變長模板,但是發現這會造成ABI不相容,所以現在我們有了新的類模板scoped_lock,它嚴格優於舊的lock_guard,所以不要使用lock_guard了。

檔案:P0006R0
概要:變數模板trait
註釋:對於每一個只包含一個靜態成員常量的trait foo ,有了一個對應的變數模板foo_v<Args…>。foo_v<Args…>等價於foo<Args…>::value。

檔案:P0152R1
概要:atomic::is_always_lock_free
註釋:一個新的靜態成員常量is_always_lock_free記錄了給定原子型別(atomic type)的操作是否總是無鎖(lock-free)的。現有的非靜態成員函式可能對同一原子型別的不同值給出不同的答案。

檔案:P0220R1, P0414R2
概要:陣列的shared_ptr
註釋:類模板shared_ptr現在可以支援C風格陣列,只需傳入T[]或T[N]作為模板引數。接受原始指標(raw pointer)的建構函式將會設定(install)合適的陣列記憶體釋放器(array deleter)。

檔案:P0163R0
概要:shared_ptr::weak_type
註釋:shared_ptr<T>現在有了一個成員型別weak_type,它是weak_ptr<T>的別名。這使得泛型程式碼不需要解構shard_ptr的型別就可以知道對應的weak_ptr型別。

檔案:P0030R1
概要:三維的斜邊長(hypotenuse)
註釋:三維斜邊長hypot(x, y, z) (可以用來計算三維空間中兩個點的距離)作為額外的過載加入 <cmath> (但沒有加入<math.h>,並且只定義在名稱空間std中)。

檔案:P0040R3
概要:更多用於未初始化記憶體的演算法
註釋:增加在未初始化的記憶體中構造物件和銷燬物件的演算法。包括分別進行預設初始化(default-initialization)和值初始化(value-initialization)的版本。

檔案:N4510
概要:記憶體分配器對不完整型別(incomplete type)的支援
註釋:這項改變放寬了記憶體分配器對它的值型別(value type)的要求,使得值型別可以是不完整型別。例如,這允許遞迴的結構,如:struct X { std::vector<X> data; };

檔案:P0092R1, P0505R0
概要:對<chrono>的改變
註釋:為時間點(time point)增加了向上取整(floor)、向下取整(ceiling)、除法(division)和四捨六入五成雙取整(rounding)。(←_←我們中出了一個除法。根據P0092R1來看,原文似有問題,增加的應該是絕對值abs而不是除法。)大多數成員函式成為constexpr函式。

檔案:P0426R1
概要:char_traits的constexpr支援
註釋:對於標準要求的所有的char_traits特化(也就是std::char_traits<char>、std::char_traits<wchar_t>、std::char_traits<char16_t>、std::char_traits<char32_t>這四個類),成員函式length、compare、find和assign現在都是constexpr成員函數了。這使得string view可以在常量表達式中更廣泛地使用。

檔案:N4387
概要:改善pair和tuple
註釋:這個變化使得pair和tuple的建構函式變為“帶條件的explicit”建構函式。只有在有某個元素的對應建構函式是explicit的時候,pair和tuple的建構函式才是explicit的。

檔案:P0435R1, P0548R1
概要:對common_type的改變
註釋:因為如果不改一下common_type,就不能稱為新標準了……

雜項

檔案:P0063R3
概要:C++引用C11
註釋:C++標準現在正式地(normatively)引用C11 (ISO/IEC 9899:2011) 為“C標準”(“The C Standard”)了。這不僅是應對ISO的要求(ISO要求對其他國際標準的引用必須引用最新發布的版本,而不是某個歷史版本),也使得我們可以使用aligned_alloc,它對於改進動態記憶體管理(dynamic memory management)非常有用。

檔案:P0180R2
概要:保留的(reserved)名稱空間
註釋:所有形如 stdN (其中 N 是一串數字)的名稱空間現在被保留了。(使用者不能使用了。)

檔案:P0175R1
概要:C庫總覽(synopsis)
註釋:一個純粹非技術性(editorial)的變化:標準庫的“C庫”部分的所有標頭檔案的內容現在在C++標準文件中以完整的總覽(synopsis)的形式展現(也就是完整列出每個標準標頭檔案包含的完整宣告),而不再是像以前一樣只列出名字。這使得與C語言中的語義不同的地方(例如增加的過載,針對language linkage的過載)更容易理解。

檔案:N4262 P0134R0 P0391R0 N4284
概要:術語“forwarding reference”、“default member initializer”、“templated entity”、“contiguous iterator”(分別對應四個檔案)
註釋:這些變化沒有正式的(normative)影響,但是它們為迄今為止只從語言規則中出現的概念建立了官方術語。精確和眾所周知的術語簡化了關於C++的討論,也簡化了規範。

未列入的檔案

展示C++17的程式碼片段合集

12345678910111213141516171819202122232425262728293031323334 std::unordered_map<std::string,std::unique_ptr<Foo>>items;std::vector<std::unique_ptr<Foo>>standby;// 如果沒有'id'元素,則把'foo'作為'id'元素插入。// 否則把'foo'儲存起來以備之後使用,將其放入standby中。// C++17以前voidf(std::stringid,std::unique_ptr<Foo>foo){auto it=items.find(id);if(it==items.end()){autop=items.emplace(std::move(id),std::move(foo));p.first->second->launch();}else{standby.push_back(std::move(foo));standby.back()->wait_for_notification();}// 注意:// * 變數'id'不能再次使用(moved-from);或者……// * ……需要使用'const string& id'作為引數,並強制複製。// * 做了兩次map查詢。有序的map可以使用lower_bound + hint,但無序的map(unordered map)用不了。// * (不能無條件呼叫emplace,因為它可能導致*foo被析構。)}// 使用C++17voidf(std::string_view id,std::unique_ptr<Foo>foo){if(auto[pos,inserted]=items.try_emplace(id,std::move(foo));inserted){pos->second->launch();}else{standby.emplace_back(std::move(foo))->wait_for_notification();}}

下面的程式碼片段展示了template <auto>的用法,例子中的類模板將一個非成員函式轉發給綁定了類例項的成員函式,並且成員函式是這個類模板的型別的一部分。

相關推薦

C++17 相比 C++14所有重大變化

摘要 本文件列舉了自C++14釋出以來,到C++17 DIS(N4660)釋出為止,應用於C++工作草案(working draft)的所有重大變化。重大變化(major changes)是以專門的檔案(paper)的形式加入的。不是每個檔案都單獨在此提及,沒有單獨

C++寫程序相比C到底有哪些不同

mfc tun com docs jsm http w3m mib dbr 1啃腦7暮0殺a斡還http://weibo.com/u/6373334892 腋6趴胖s斷堵c苑寥6gwhttp://shufang.docin.com/jwo55353 7懈5qyof6醇b

[譯]C++17, 語言核心層有哪些新的變化

看到一個介紹 C++17 的系列博文(原文),有十來篇的樣子,覺得挺好,看看有時間能不能都簡單翻譯一下,這是第一篇~ C++11, C++14, 以及 C++17. 我猜你已經看出了其中的命名模式: 今年(2017)的晚些時候,我們便會迎來新的C++標準(C++17). 今

C++相比其他語言的優勢

傳統上認為,C++相對於目前一些新潮的語言,如Java、C#,優勢在於程式的執行效能。這種觀念並不完全。如果一個人深信這一點,那麼說明他並沒有充分了解和理解C++和那個某某語言。同時,持有這種觀念的人,通常也是受到了某

C++17/14/11 個人備忘

給自己看的。 我的情況:從 C++ Primer 第五版 入門,該版基於C++11,但不是專門講C++11的,只提到了部分相關內容。後來自己看過一些介紹 C++11相關的書,查過一些資料。14/17沒去了解過。 從17開始,再到14,再到11 17 // 似乎正式

C/C++遍歷目錄下的所有文件(Windows/Linux篇,超詳細)

檢查 msd 字符 size tro 也會 結構 () alt 前面的一篇文章我們講了用Windows API遍歷一個目錄下的所有文件,這次我們講用一種Windows/Linux通用的方法遍歷一個目錄下的所有文件。 Windows/Linux的IDE都會提供一個頭文件—

你需要了解的 C++ 17 Top 19 新特性(附精彩評論)

turn ane res 標準屬性 padding about ref list 5.0 什麽是 C++17? C++17(或 C++1z)是繼 C++14 之後 C++ 編程語言 ISO/IEC 標準的下一次修訂的非正式名稱。C++17 現在功能已齊全,正在成為國際標準

Linux C 讀取文件夾下所有文件(包括子文件夾)的文件名(轉)

文件中 其中 文件類型 sizeof basepath 文件 lose sed int Linux C 下面讀取文件夾要用到結構體struct dirent,在頭#include <dirent.h>中,如下: 1 #include <dirent.h

cocos2d JS 本地緩存存儲登陸記住賬號密碼->相當C++中的UserDefault

work 定義 cal func png 移除 com 判斷 方式 在cocos-js 3.0以上的版本中,當我們用到本地存儲的時候,發現以前用到的UserDefault在JS中並沒有導出,而是換成了LocalStorage。 在LocalStorage.h文件中我

用nodejs搭建類似C++的服務器後臺.類似網易pomelo

情況 分享 .cn 朋友 簡單 .com 結構 ejs 父進程 實際的情況,用nodejs跑業務,非常的快,只要用好其無阻塞和回調這兩點,處理速度真的是杠杠的。 從年初開始,我用nodejs搭建了類似C++的服務器後臺,也想和做同樣的事情的朋友分享,本服務平臺因為已經實際商

C++入門經典-例2.14-使用移位運算

使用 name clas span 二進制 位運算 hide 整形 img 1:代碼如下: // 2.14.cpp : 定義控制臺應用程序的入口點。 // #include "stdafx.h" #include <iostream> using name

17-10-5.c#類的使用與訪問........對類的調用還有些模糊..

c# 訪問 1-1 -1 png blog 使用 logs .cn 17-10-5.c#類的使用與訪問........對類的調用還有些模糊..

C++遍歷路徑下的所有文件

highlight true file bsp char 函數 cmp ron 標識 intptr_t類型用於記錄文件夾句柄,註意該類型不是指針類型,而是int型的重定義。 _finddata_t結構體類型用於記錄文件信息。 _finddata_t結構體定義如下 str

delphi的bpl、dcp 、dcu文件意義(BPL相當C++中的DLL,DCP相當C++中的Lib,編譯時需要)

cti function 同時 就會 新建 art img runt 既然 BPL 英文全稱 Borland Package library ,是一種特殊的DLL文件,用於代碼重用和減少可執行文件。編譯bpl時,僅需要添加相應功能的pas文件,如果有窗體,

一次lr異常Error: C interpreter run time error: Action.c (17): Error -- memory violation : Exception ACCESS_VIOLATION received問題分析

exceptio err png 今天 ret pos 通過 ima qq群 今天qq群裏人問我一個問題 他想將token變量換成lr中的參數 所以,他通過lr_save_string函數轉換 編譯也不報錯,但是運行提示: 解決方法: 一次lr異常Error: C

c++17 filesystem, regex 遍歷目錄

擴展 clas include directory dir 正則 cout 目錄 rect c++17 FS 還是挺好用的 #include<filesystem> #include<regex> //正則表達式 namespace fs =

C語言題:自動對所有的整數進行求和並打印出結果

要求: 編寫一個程式,要求使用者輸入一串整數和任意數目的空格,這些整數必須位於同一行中,但允許出現在改行中的任何位置。當用戶按下鍵盤上的“Enter”鍵時,資料輸入結束。程式自動對所有的整數進行求和並打印出結果。   注意: scanf的返回值:返回成功讀入的資料項數。

c#遍歷資料夾獲得所有檔案

c#遍歷資料夾獲得所有檔案 在c#中,想要獲得一個資料夾下的所有子目錄以及檔案十分簡單。 首先,獲取目錄的情況下,DirectoryInfo.GetDirectories():獲取目錄(不包含子目錄)的子目錄,返回型別為DirectoryInfo[],支援萬用字元查詢; 其次,獲取檔案的

c語言實現輸出10000內所有素數,5個換一行

1 #include<stdio.h> 2 int main() 3 { 4 int i,j,k=0; 5 for(i=2;i<10000;i++) 6 { 7 for(j=2;j*j<=i;j++) 8

c語言實現顯示10000內所有素數,5個換一行

#include<stdio.h> int main() { int i,j,k=0; for(i=2;i<10000;i++) { for(j=2;j*j<=i;j++) if(i%j==0)