ISO C++ 語言標準化委員會已批准了構成國際標準「C++26」的最終規範版本。此規格中提出的特性已在 GCC、Clang 和 Microsoft Visual C++ 編譯器中部分支援。支援 C++26 的標準函式庫已在 Boost 專案中實作。
在接下來的兩個月裡,經批准的規範將進入文件編制階段,期間將進行編輯修正,以解決拼字錯誤和錯字。 11月初,最終版本的文件將提交給ISO,以正式名稱ISO/IEC 14882:2026發布。
C++26 的主要特性:
- 已實作契約程式設計元素(契約),允許您使用三個新運算子定義正式的介面規格:`pre`(前置條件)、`post`(後置條件)和 `contract_assert`(斷言檢查)。 `pre` 運算子定義呼叫前必須滿足的前置條件(輸入驗證);`post` 運算子定義執行後必須滿足的條件(輸出要求);`contract_assert` 運算子定義引發異常的條件。此功能將在 GCC 16 中提供。 `int f(const int x) pre (x != 1) // 輸入要求 post (r : r == x && r != 2) // 結果需求;r 是結果的值 { contract_assert (x != 3); return x; }`
- 新增了反射支持,允許在編譯時監視和修改程式元素。新增了用於取得語法結構元資訊的運算子「^^」和用於執行逆變換的運算子「[:…:]」。建議使用 std::meta 庫來轉換和處理檢查過程中獲取的信息,並提供諸如常量計算等功能。反射支援將在 GCC 16 中加入。 constexpr int i = 42, j = 42; constexpr std::meta::info r = ^^i, s = ^^i; static_assert(r == r && r == s); static_assert(^^i != ^^j); // 'i' 和 'j' 的值不同。 static_assert(constant_of(^^i) == constant_of(^^j)); // 'i' 和 'j' 相同 static_assert(^^i != std::meta::reflect_constant(42)); // 與值 42 不同
- 新增了「template for」功能,用於在編譯時以類似常規 for 迴圈的方式遍歷參數包、元組物件和反射結果(元物件)等元素。執行「template for」時,循環體會針對每個元素展開,並且每次迭代都在單獨的作用域中處理,循環中變化的變數在該作用域中保持不變。在反射上下文中,「template for」可用於遍歷類別或枚舉的屬性。此功能將在 GCC 16 中可用。例如,`void f() { template for (constexpr int I : std::array{1, 2, 3}) { static_assert(I < 4); } }` 將展開為:`void f() { { constexpr auto&& __range = std::array{1, 213); constexpr auto __expansion-size = __range.end() — __begin; // 3 { constexpr int I = *(__begin + 0); static_assert(I < 4); } { constexpr int I = *(__begin + 1); static_x(I] constexpr int I = *(__begin + 1); static_assert(I < 4); } } }
- 新增了用於非同步和平行程式碼執行的 std::execution 框架。它提供了調度器物件(定義工作調度器,例如線程、線程池、GPU 或事件循環)、發送器物件(定義要執行的工作)和接收器物件(處理結果)。 using namespace std::execution; scheduler auto sch = thread_pool.scheduler(); sender auto begin = schedule(sch); sender auto hi = then(begin, []{ std::cout < "Hello world! Have hi = then(begin, []{ std::cout < "Hello world! Have hian int."; return; [](int arg) { return arg + 42; }); auto [i] = this_thread::sync_wait(add_42).value();
- std::simd 庫已添加,用於使用標準 C++ 類型系統,透過 AVX-512 和 NEON 等 SIMD 指令集並行化資料操作。 a = {1.0f, 2.0f, 3.0f, 4.0f}; std::simd b = {5.0f, 6.0f, 7.0f, 8.0f}; std::simd result = a + b;
- 本文提出了一個可變大小向量(陣列)`std::inplace_vector` 的實作。它分配在堆疊上,堆疊的大小在編譯時確定。其 API 與 `std::vector` 類似,但陣列元素儲存在內部,而不是堆上。 `inplace_vector a(10); inplace_vector b(std::move(a)); assert(a.size() == 10);`
- 已新增“#embed”指令,用於將二進位資源嵌入到程式碼中。 const unsigned char icon_display_data[] = { #embed "art.png" };
- 新增了在編譯時產生和處理 constexpr 上下文中發生錯誤時異常的支援。 constexpr std::optional checked_divide(unsigned n, unsigned d) { try { return divide(n, d); } catch (...) { return std::nullopt; } } constexpr date parse_date(std::string_view input) { auto [correct, year, month, daysear] ctre::match<“([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})”>(input); if (!correct) { throw incorrect_date{input}; } return build_date(ydayd_date(year);
- std::hive 資料結構專為無序資料儲存和記憶體重複使用而設計,可重複使用已刪除元素釋放的記憶體。該結構針對高強度、任意順序的元素添加和刪除工作負載進行了最佳化。與陣列不同,在 std::hive 中刪除元素不會移動其他元素,而是將已刪除的元素標記為空,並在新增元素時填入空出的位置。
- 新增了基於 BLAS 的線性代數 API 的 std::linalg 函式庫。
- 新增了對危險指標同步機制的支持,該機制可防止在未加鎖的情況下釋放其他執行緒正在存取的物件所佔用的記憶體。當一個物件被刪除時,它只會被標記為已刪除,但只有當所有執行緒都釋放了存取該物件時設定的危險指標後,該物件佔用的記憶體才會被釋放。
- 新增了對 RCU(讀取-複製-更新)同步機制的支援。寫入操作會建立一個新的物件實例,而讀取操作不會阻塞,而是繼續使用舊實例。更改完成後,新實例變為活動狀態,並對其執行新的讀取操作;舊實例在讀取執行緒完成後會被刪除。
- 為了加強標準庫的安全性,我們進行了一些更改,例如檢查有效值和緩衝區溢位。例如,在存取元素「constexpr reference operator[](size_type idx) const;」時,增加了對條件「idx < size()」的檢查。
- 提供了使用 constexpr 關鍵字和 new 運算子的變體(placement new)在編譯時將物件放置到預先分配記憶體中的功能。
- 在「constexpr」上下文中新增了對結構化綁定的支持,這意味著對常數表達式的引用現在本身也可以是常數表達式。已實現對數組和簡單結構體的支援。 constexpr int arr[] = {1, 2}; constexpr auto [x, y] = arr;
- 結構化綁定現在支援“...”語法,以指定捕獲分配序列中剩餘元素數的包。 auto [x,y,z] = f(); // 變數 x、y、z 將包含 f() 傳回的三個元素。 auto [...xs] = f(); // 套件 xs 將包含 f() 傳回的所有元素。 auto [x, ...rest] = f(); // x 將包含第一個元素,rest 將包含其餘元素。 auto [x, y, ...rest] = f(); // x 將包含第一個元素,y 將包含第二個元素,rest 將包含第三個元素。 auto [x, ...rest, z] = f(); // x 將包含第一個元素,rest 將包含第二個元素,z 將包含第三個元素。
- 添加了對類型的“簡單可重定位性”的支持,允許通過在內存中克隆給定類型的對象而不調用構造函數或析構函數來優化其移動。為類別實作了memberwise_trivially_relocatable和memberwise_replaceable屬性,並新增了trivially_relocate_at和trivially_relocate函數,用於一個或多個物件的低階移動。
- 已實作將 main() 函數附加到全域模組以及在命名模組中定義 main() 函數的功能。
- 新增了變數運算子“friend”(“friend Ts...”)。
- 為結構化綁定實現了屬性;
- 新增了語法“= delete("reason")”。
- 基本字元集包括“@”、“$”和“`”。
- 提供了在 if 和 switch 語句中使用結構化綁定作為條件的功能。
- 增加了在一個範圍內使用多個名為“_”的佔位符變數的能力,例如,以下構造現在是正確的:struct S { int _, _; }; void func() { int _, _; } 無效其他() { int _; // 之前在 -Wunused 模式下會顯示警告 } 模式下會顯示警告 }
- 提供在某種上下文中使用字串文字的能力,在該上下文中,字串文字不用於初始化字元數組,也不會出現在結果程式碼中,而僅在編譯期間用於診斷訊息和預處理,例如作為 _Pragma、asm、extern、static_assert、[[deprecated]] 和 [[nodiscard]] 指令和屬性的參數。
- 新增了內建函數:「__builtin_is_within_lifetime」 用於檢查聯合體中的替代函數是否處於活動狀態,以及「__builtin_is_virtual_base_of」 用於檢查基底類別是否為虛擬函數。
- 實現了簡單的無限循環,沒有出現未定義行為。
- 確保在刪除指向不完整類型的指標時顯示錯誤。
- 使用省略號且前面沒有逗號來定義可變參數的語法(例如,指定“void e(int…)”而不是“void e(int, …)”)已被棄用。
- 禁止使用巨集來聲明模組。
- 算術運算中枚舉值的隱式轉換已被棄用。 int main() { enum E1 { e }; enum E2 { f }; bool b = e <= 3.7; // 已棄用 int k = f - e; // 已棄用 int x = +f - e; // 正常 }
- 已停止支援直接數組比較。 int arr1[5]; int arr2[5]; bool same = arr1 == arr2;
- is_trivial 模板類別已被棄用。
來源: opennet.ru
