最終更新日時: 2026年07月21日 15時10分52秒 (JST)
rotarymars が更新

履歴 編集

# C++23

## 概要

C++23とは、2023年中に改訂され、ISO/IEC 14882:2024で標準規格化されたC++バージョンの通称である。

このバージョンは、策定中のためC++2bと呼ばれることがある。「(C++20である2020年の次の) 202b年にリリースされる」という伏せ字として「b」が使われているが、3年周期に次のバージョンが策定されることが決まっているため、伏せ字になっている年数がずれることはない。

## 言語機能

### 変数

言語機能 | 説明
--- | ---
(符号付き)`size_t`リテラルのためのサフィックス | `42z`/`42Z`とすることで`size_t`に対応する符号付き整数型のリテラルとする
暗黙的なムーブを簡略化 | 参照を返す関数の`return`文で暗黙的にムーブされない問題を修正

これらに加えて、ライブラリ機能として拡張浮動小数点数型が定義された。`<stdfloat>`を参照。

### 関数

言語機能 | 説明
--- | ---
スコープと名前探索の仕様整理 | 複雑で不完全になっているスコープと名前探索の仕様を整理し、一部の問題を解決する
無意味なexport宣言を禁止する | いくつかの不必要な宣言に対するモジュールexportを禁止する

### 制御構文

言語機能 | 説明
--- | ---
初期化文での型の別名宣言を許可 | `for (using T = int; T e : v) {}`を許可
範囲for文が範囲初期化子内で生じた一時オブジェクトを延命することを規定 | 範囲初期化子内で生じた一時オブジェクトは範囲for文の終わりまで延命される
複合文の末尾へのラベルを許可 | C互換のため、複合文の末尾でのgoto文のラベルを許可する

### クラス

言語機能 | 説明
--- | ---
自身のオブジェクトを明示的にパラメータとして指定する | メンバ関数が`*this`の型・オブジェクトをパラメータとしてとり、`*this`オブジェクトがconst/非const、左辺値/右辺値であるかをメンバ関数内で識別できるようにする
アクセス制御の異なるメンバ変数のレイアウトを宣言順に規定 | アクセス制御の異なるメンバ変数のレイアウトは並び替えを許可されていたが宣言順に規定する
添字演算子の多次元サポート | `operator[](int x, int y, int z)`のように添字演算子のオーバーロードで複数のパラメータをとることを許可
`this`ポインタをもつ必要のない演算子を`static`として宣言できるようにする | 状態をもたないいくつかの演算子を`static`として宣言できるようにする

### 文字列

言語機能 | 説明
--- | ---
異なる文字エンコーディングをもつ文字列リテラルの連結を不適格とする | `auto a = u8"" L"";`のような異なる文字エンコーディング同士での文字列リテラルの連結を禁止する
エスケープシーケンスの区切り | エスケープシーケンスの範囲を明確にする構文を追加する
文字・文字列リテラル中の数値・ユニバーサルキャラクタのエスケープに関する問題解決 | 数値エスケープが文字エンコーディングに変換されずコードユニット値を直接指定することなどを明確化する
1ワイド文字に収まらないワイド文字リテラルを禁止する | エンコード結果として`wchar_t`の大きさに収まらないワイド文字リテラルを禁止する
名前付きユニバーサルキャラクタ名 | 16進数のユニバーサルキャラクタだけでなく、その文字の名前を入力できるようにする

### テンプレート

言語機能 | 説明
--- | ---
変数テンプレートの部分特殊化を許可 | 変数テンプレートの部分特殊化を許可するために部分特殊化の仕様を汎用化
継承コンストラクタからのクラステンプレート引数の推論 | 継承コンストラクタからもクラステンプレート引数を推論できるようにする

### 定数式

言語機能 | 説明
--- | ---
`if consteval` | コンパイル時の文脈かどうかで分岐させる
定数式の文脈での`bool`への縮小変換を許可 | `if constexpr(flags & Flags::Exec)`や`static_assert(N);`を許可
定数式内での非リテラル変数、静的変数・スレッドローカル変数およびgotoとラベルの存在を許可する | コンパイル時に評価されない限り、定数式内に静的変数・スレッドローカル変数およびgoto文とラベルを含むことを許可する
静的な診断メッセージの文字エンコーディング | `static_assert`や`[[deprecated]]`などの診断メッセージの文字集合に関する要件をなくす
`constexpr`関数が定数実行できない場合でも適格とする | 定数式実行できない関数であっても、実際にコンパイル時に評価されない限り`constexpr`指定することを許可する
`constexpr`関数内での`static constexpr`変数を許可 | `constexpr`関数のローカルで定数を定義できるようにする
`constexpr`関数内で`consteval`関数を呼び出せない問題を軽減 | `consteval`呼び出しを含む`constexpr`関数を条件付きで`consteval`関数とみなすようにする

### ラムダ式

言語機能 | 説明
--- | ---
ラムダ式で`()`を省略できる条件を緩和 | 修飾や戻り値型をともなってもパラメータリストが空であれば`()`を省略できる
ラムダ式に対する属性 | ラムダ式のいくつかの箇所に属性を記述できるようにする

### 属性

言語機能 | 説明
--- | ---
コード内容の仮定をコンパイラに伝えるassume属性 | 最適化のために、コードの仮定をコンパイラに伝える属性を標準化する

### プリプロセッサ

言語機能 | 説明
--- | ---
文字リテラルエンコーディングを一貫させる | プリプロセッサの条件式での文字リテラルの扱いをC++式と同様にする
`elif`/`elifdef`/`elifndef`のサポートを追加 | `#if`/`#ifdef`/`#ifndef`に対応する複数条件命令のサポートを追加する
`#warning`のサポートを追加 | 多くのC++コンパイラが実装していたプリプロセス時の警告`#warning message`を正式サポート

### 字句解析

言語機能 | 説明
--- | ---
汎用的なソースコードのエンコーディングとしてUTF-8をサポート | すべてのコンパイラはUTF-8文字コードのソースコードをサポートしなければならない
行末スペースを無視するよう規定 | 行末が「`\` 」でおわっていた場合にMSVCは行の継続をしない実装になっていたため動作を共通化するため仕様を規定

### 小さな変更

言語機能 | 説明
--- | ---
更新された定義済みマクロ | 標準規格で定義されたマクロの更新
参照するPOSIX規格を更新 | 新しいPOSIX規格の機能を標準C++が参照していたため、参照するPOSIX規格のバージョンを更新

## ライブラリ更新の概要

### 新ライブラリ

- C++標準ライブラリ全体のモジュールとして`std`、C互換ライブラリ全体のモジュールとして`std.compat`を追加
- スタックトレースを取得するためのライブラリとして`<stacktrace>`を追加
- CとC++の間でのアトミック操作の相互運用のため、C互換ライブラリとして`<stdatomic.h>`を追加
- 外部から提供されるメモリバッファでストリーム処理を行うライブラリとして`<spanstream>`を追加
- 正常値とエラー値のどちらかを持つクラスおよびライブラリとして`<expected>`を追加
- 多次元配列ビューのライブラリとして`<mdspan>`を追加
- ノードベースではないソート済みキーによる順序付き連想コンテナのライブラリとして、`<flat_map>`と`<flat_set>`を追加
- 書式指定で出力するライブラリとして`<print>`を追加
- コルーチンによるRangeの生成をサポートする`<generator>`を追加
- 拡張浮動小数点数のライブラリとして`<stdfloat>`を追加

### コンテナ

- `std::stack`と`std::queue`に、イテレータのペアをとるコンストラクタを追加
- `auto v = std::vector(v, alloc);`のようなアロケータ引数をともなう場合のクラステンプレートのテンプレート引数推論が動作しなかったため、各コンテナクラスのコンストラクタにおけるアロケータパラメータの型を`const Allocator&`から`const std::type_identity_t<Allocator>&`に修正し、コンテナアダプタの推論補助の制約を修正
- N要素のメモリアロケート時にアロケータが実際にどれくらいのメモリを確保したかを得られるインタフェースとして、
  - `std::allocator`クラスに、`allocate_at_least()`メンバ関数を追加
  - `std::allocator_traits`クラスに、`allocate_at_least()`関数を追加
- `std::pair`の転送コンストラクタにデフォルトテンプレート引数を追加することで、`{}`のような型推論ができない引数を渡した場合でも完全転送が行われるよう修正
- 順序付き連想コンテナの要素削除の処理について、一時オブジェクトのコストを抑える拡張が行われた
  - `std::map::erase()`
  - `std::map::extract()`
- `<ranges>`に、複数の範囲を綴じ合わせる`std::views::zip`を追加
- `<ranges>`に、複数の範囲の直積をとる`std::views::cartesian_product`を追加
- Rangeから任意のコンテナに変換するRangeアダプタ`std::ranges::to()`を追加
- Rangeから任意のコンテナに変換するために、可変長のコンテナ (`std::array`以外) に、以下の機能を追加：
  - Rangeから変換するコンストラクタ
  - Rangeを挿入する`insert_range()`メンバ関数
  - Rangeを先頭に追加する`prepend_range()`メンバ関数
  - Rangeを末尾に追加する`append_range()`メンバ関数
  - Rangeを代入する`assign_range()`メンバ関数
- ユーザー定義のRangeアダプタがパイプライン演算子 `|` をサポートしやすくするために、`<ranges>`に`std::ranges::range_adaptor_closure`クラスを追加
- `<ranges>`に、Rangeを連結させる`join_with`を追加
- Rangeを指定の大きさで分割する`std::views::chunk`と、Rangeを指定の大きさの隣接要素で分割する`std::views::slide`を追加
- Rangeを条件一致する間の要素で分割する`std::views::chunk_by`を追加
- `<ranges>`に、Rangeを等間隔からなるRangeに変換する`std::views::stride`を追加
- `<ranges>`に、Rangeをムーブするための`std::views::as_rvalue`を追加
- `<ranges>`に、指定した値をN回繰り返すRangeを生成する`std::views::repeat`を追加
- `<ranges>`に、Rangeをインデックス付きでループさせる`std::views::enumerate`を追加

### アルゴリズム

- `<algorithm>`に、範囲の先頭が指定した範囲と合致するかを判定する`std::ranges::starts_with()`、範囲の末尾が指定した範囲と合致するかを判定する`std::ranges::ends_with()`を追加
- `<algorithm>`に、要素を左シフトさせるRangeアルゴリズム`std::ranges::shift_left()`、要素を右シフトさせるRangeアルゴリズム`std::ranges::shift_right()`を追加
- `<algorithm>`に、範囲の末尾から要素を検索する以下のアルゴリズムを追加：
  - `std::ranges::find_last()`
  - `std::ranges::find_last_if()`
  - `std::ranges::find_last_if_not()`
- `<algorithm>`に、範囲に特定の値が含まれているかを判定する`std::ranges::contains()`、`std::ranges::contains_subrange`を追加
- `<algorithm>`に、数値に限定しない汎用的な畳み込みアルゴリズムとして、以下を追加：
  - `std::ranges::fold_left()`
  - `std::ranges::fold_left_first()`
  - `std::ranges::fold_right()`
  - `std::ranges::fold_right_last()`
  - `std::ranges::fold_left_with_iter()`
  - `std::ranges::fold_left_first_with_iter()`
- `<numeric>`に、連番を生成するRangeアルゴリズム`std::ranges::iota()`を追加

### 文字列

- `std::basic_string`クラスと`std::basic_string_view`クラスに、文字列内に指定した文字・文字列が含まれているかを判定するメンバ関数`contains()`を追加
- `std::basic_string_view`のコンストラクタに、範囲をとるオーバーロードを追加
- `std::string s = nullptr;`のような文字列オブジェクトに`nullptr`を代入するようなコードはバグの元であるため、`std::basic_string`と`std::basic_string_view`に、`nullptr_t`をとるコンストラクタをdelete定義として追加
- `std::basic_string`クラスに、resize時に任意の初期化を行う`resize_and_overwrite()`メンバ関数を追加
- `std::basic_string`クラスのコンストラクタと`substr()`メンバ関数に一時オブジェクトのオーバーロードを追加
- `std::format()`関数でRange・コンテナ、`std::tuple`、`std::pair`を出力できるよう、`std::formatter`に特殊化を追加
  - Range・シーケンスコンテナは`[1, 2, 3]`、`["hello", "world"]`、`['a', 'b', 'c']`のように出力される
  - 連想コンテナの場合、`std::map<int, int>{{1, 2}, {3, 4}}`は`{1: 2, 3: 4}`のように出力され、`std::set<int>{1, 2, 3}`は`{1, 2, 3}`のように出力される
  - `std::tuple`、`std::pair`は`(1, 2)`のように出力される
- `std::format()`関数のフォーマット指定子としてデバッグ指定「`"?"`」を追加。これは文字・文字列を引用符で囲み、エスケープシーケンスをエスケープする
  - ただし、Range・コンテナ中の文字・文字列はデフォルトでエスケープされる
  - `format("{:?}", "h\tello")`は`"h\tello"`のように出力される

### 入出力

- `std::basic_ostream`クラスの`operator<<`に、`const volatile void*`をとるオーバーロードを追加
- ファイルを開く際のオプションとして、排他モードを表す`noreplace`を追加

### 関数オブジェクト

- `std::invoke()`の戻り値型を指定するバージョンである`std::invoke_r()`を追加
- `std::function`クラスと等価な機能をもつ、ムーブのみ可能な`std::move_only_function`クラスを追加
- ユーザー定義のRangeアダプタがパイプライン演算子 `|` をサポートしやすくするために、末尾から引数を束縛する`std::bind_back()`関数を追加

### メモリ

- `<memory>`に、レガシーC関数からスマートポインタへの直接出力をサポートする、スマートポインタアダプタ`std::out_ptr`と`std::inout_ptr`を追加
- `std::unique_ptr`クラスを`constexpr`に対応
- `<memory>`に、オブジェクトの生存期間を開始することを明示する関数として、`std::start_lifetime_as()`と`std::start_lifetime_as_array()`を追加
- `<bit>`に、値のバイト入れ替え (エンディアン変換) を行う`std::byteswap()`関数を追加

### ユーティリティ

- `std::visit()`に指定できるバリアントオブジェクトを、直接的な「`std::variant`型の特殊化であること」という制約を緩和し、`std::variant`から派生した型も許可
- `<utility>`に、列挙値を基底型に変換する`std::to_underlying()`関数を追加
- `<utility>`に、 (主に) メンバ変数を転送するため、指定された型の`const`性と参照修飾で引数を転送する`std::forward_like()`関数を追加
- `std::optional`クラスにモナド操作としてメンバ関数`and_then()`、`transform()`、`or_else()`を追加
- 到達しないパスであることを表明する関数`std::unreachable()`を追加
- `std::bitset`クラスをさらに`constexpr`対応

### 型情報

- `std::type_info`クラスの`operator==`を`constexpr`に対応

### 型特性

- `<type_traits>`に、スコープ付き列挙型かを判定する型特性`std::is_scoped_enum`を追加
- `<type_traits>`に、一時オブジェクトの参照への束縛を検出するための型特性として、以下を追加：
  - `std::reference_constructs_from_temporary`
  - `std::reference_converts_from_temporary`
- `<type_traits>`に、暗黙的に構築される型かを判定する型特性`std::is_implicit_lifetime`を追加

### C互換ライブラリ

- `<cstdlib>`ヘッダと`<cmath>`ヘッダの多くの関数を`constexpr`に対応

### 機能の非推奨化

- `std::aligned_storage`と`std::aligned_union`を非推奨化。これらの機能は未定義動作を引き起こし、間違った保証が行われ、よくないAPI設計が行われていたため、非推奨とする
  - `std::aligned_storage`の代わりに`alignas(T) std::byte[sizeof(T)];`を使用することを推奨する
  - `std::aligned_union`の代わりに`alignas(Ts...) std::byte[std::max({sizeof(Ts)...})];`を使用することを推奨する
- `std::allocator`のメンバ型`is_always_equal`を非推奨化。これはアロケータが状態をもたないことを表す型でありデフォルトでは`true_type`となっている。状態をもつユーザー定義のアロケータ型でこのメンバ型の上書きを忘れることでバグが埋め込まれてしまっていたため誤用防止のために非推奨とする
- `<limits>`の以下の非正規化数に関する機能を非推奨化。これらの機能は必ずしもコンパイル時に決まらない可能性のある値であり有用でないため、非推奨とする
  - `std::numeric_limits::has_denorm`
  - `std::numeric_limits::has_denorm_loss`
  - `std::float_denorm_style`

### 機能の削除

- ガベージコレクションの実装にうまく役立てられなかった、ガベージコレクション実装のサポートをする以下の機能を削除する：
  - `std::declare_reachable()`
  - `std::undeclare_reachable()`
  - `std::declare_no_pointers()`
  - `std::undeclare_no_pointers()`
  - `std::get_pointer_safety()`
  - `std::pointer_safety`
  - `__STDCPP_STRICT_POINTER_SAFETY__`マクロ

### 取り決め

- 以下のヘッダの一部機能をフリースタンディングライブラリとして追加：
  - `<utility>`
  - `<tuple>`
  - `<memory>`
  - `<functional>`
  - `<ratio>`
  - `<iterator>`
  - `<ranges>`