概要
C++23とは、2020年中に改訂され、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文字コードのソースコードをサポートしなければならない |
小さな変更
言語機能 | 説明 |
---|---|
更新された定義済みマクロ | 標準規格で定義されたマクロの更新 |
参照するPOSIX規格を更新 | 新しいPOSIX規格の機能を標準C++が参照していたため、参照するPOSIX規格のバージョンを更新 |
行末スペースを無視するよう規定 | 行末が「\ 」でおわっていた場合にMSVCは行の継続をしない実装になっていたため動作を共通化するため仕様を規定 |
ライブラリ更新の概要
新ライブラリ
- 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
の転送コンストラクタにデフォルトテンプレート引数を追加することで、{}
のような型推論ができない引数を渡した場合でも完全転送が行われるよう修正- 順序付き連想コンテナの要素削除の処理について、一時オブジェクトのコストを抑える拡張が行われた
<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::starts_with()
、範囲の末尾が指定した範囲と合致するかを判定するstd::ends_with()
を追加<algorithm>
に、要素を左シフトさせるRangeアルゴリズムstd::ranges::shift_left()
、要素を右シフトさせるRangeアルゴリズムstd::ranges::shift_right()
を追加<algorithm>
に、範囲の末尾から要素を検索する以下のアルゴリズムを追加:<algorithm>
に、範囲に特定の値が含まれているかを判定するstd::ranges::contains()
、std::ranges::contains_subrange
を追加<algorithm>
に、数値に限定しない汎用的な畳み込みアルゴリズムとして、以下を追加:<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)
のように出力される
- Range・シーケンスコンテナは
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>
に、一時オブジェクトの参照への束縛を検出するための型特性として、以下を追加:
C互換ライブラリ
機能の非推奨化
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>
の以下の非正規化数に関する機能を非推奨化。これらの機能は必ずしもコンパイル時に決まらない可能性のある値であり有用でないため、非推奨とする
機能の削除
- ガベージコレクションの実装にうまく役立てられなかった、ガベージコレクション実装のサポートをする以下の機能を削除する:
取り決め
- 以下のヘッダの一部機能をフリースタンディングライブラリとして追加: