C++23
概要
C++23とは、2023年中に改訂される予定の、C++バージョンの通称である。
このバージョンは、策定中のためC++2bと呼ばれることがある。「(C++20である2020年の次の) 202b年にリリースされる」という伏せ字として「b」が使われているが、3年周期に次のバージョンが策定されることが決まっているため、伏せ字になっている年数がずれることはない。
言語機能
変数
言語機能 |
説明 |
(符号付き)size_t リテラルのためのサフィックス |
42z /42Z とすることでsize_t に対応する符号付き整数型のリテラルとする |
エスケープシーケンスの区切り |
エスケープシーケンスの範囲を明確にする構文を追加する |
暗黙的なムーブを簡略化 |
参照を返す関数のreturn 文で暗黙的にムーブされない問題を修正 |
これらに加えて、ライブラリ機能として拡張浮動小数点数型が定義された。<stdfloat>
を参照。
関数
言語機能 |
説明 |
スコープと名前ルックアップの仕様整理 |
複雑で不完全になっているスコープと名前ルックアップの仕様を整理し、一部の問題を解決する |
無意味なexport宣言を禁止する |
|
制御構文
言語機能 |
説明 |
初期化文での型の別名宣言を許可 |
for (using T = int; T e : v) {} を許可 |
範囲for文が範囲への参照を延命することを規定 |
|
関数末尾のラベルを許可 |
C互換のため、関数末尾でのgoto文のラベルを許可する |
クラス
言語機能 |
説明 |
自身のオブジェクトを明示的にパラメータとして指定する |
メンバ関数が*this の型・オブジェクトをパラメータとしてとり、*this オブジェクトがconst/非const、左辺値/右辺値であるかをメンバ関数内で識別できるようにする |
アクセス制御の異なるメンバ変数のレイアウトを宣言順に規定 |
アクセス制御の異なるメンバ変数のレイアウトが実装によって異なっていたため仕様を規定 |
添字演算子の多次元サポート |
operator[](int x, int y, int z) のように添字演算子のオーバーロードで複数のパラメータをとることを許可 |
this ポインタをもつ必要のない演算子をstatic として宣言できるようにする |
|
文字列
言語機能 |
説明 |
異なる文字エンコーディングをもつ文字列リテラルの連結を不適格とする |
auto a = u8"" L""; のような異なる文字エンコーディング同士での文字列リテラルを連結を禁止する |
文字・文字列リテラル中の数値・ユニバーサルキャラクタのエスケープに関する問題解決 |
|
1ワイド文字に収まらないワイド文字リテラルを禁止する |
エンコード結果としてwchar_t の大きさに収まらないワイド文字リテラルを禁止する |
名前付きユニバーサルキャラクタ名 |
16進数のユニバーサルキャラクタだけでなく、その文字の名前を入力できるようにする |
テンプレート
言語機能 |
説明 |
部分特殊化の汎用化仕様 |
変数テンプレートの部分特殊化を許可するために部分特殊化の仕様を汎用化 |
継承コンストラクタからのクラステンプレート引数の推論 |
|
定数式
言語機能 |
説明 |
if consteval |
コンパイル時の文脈かどうかで分岐させる |
定数式の文脈でのbool への縮小変換を許可 |
if constexpr(flags & Flags::Exec) やstatic_assert(N); を許可 |
定数式内での非リテラル変数の使用を含められないようにする |
定数式内で静的変数・スレッドローカル変数およびgoto文とラベルを含められない制限を設ける |
静的な診断メッセージの文字エンコーディング |
static_assert や[[deprecated]] などの診断メッセージの文字集合に関する要件をなくす |
constexpr 関数のすべての引数が定数実行できない場合でも適格とする |
|
constexpr 関数内でのstatic constexpr 変数を許可 |
|
constexpr 関数内でconsteval 関数を呼び出せない問題を緩和 |
|
ラムダ式
言語機能 |
説明 |
ラムダ式で() を省略できる条件を緩和 |
キャプチャや修飾をともなってもパラメータリストが空であれば() を省略できる |
ラムダ式に対する属性 |
ラムダ式のいくつかの箇所に属性を記述できるようにする |
属性
プリプロセッサ
言語機能 |
説明 |
文字リテラルエンコーディングを一貫させる |
プリプロセッサの条件式での文字リテラルの扱いをC++式と同様にする |
elif /elifdef /elifndef のサポートを追加 |
#if /#ifdef /#ifndef に対応する複数条件命令のサポートを追加する |
#warning のサポートを追加 |
多くのC++コンパイラが実装していたプリプロセス時の警告#warning message を正式サポート |
汎用的なソースコードのエンコーディングとして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::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>
に、範囲の末尾から要素を検索する以下のアルゴリズムを追加:
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"
のように出力される
入出力
関数オブジェクト
メモリ
ユーティリティ
型情報
型特性
C互換ライブラリ
機能の非推奨化
機能の削除
- ガベージコレクションの実装にうまく役立てられなかった、ガベージコレクション実装のサポートをする以下の機能を削除する:
取り決め
- 以下のヘッダの一部機能をフリースタンディングライブラリとして追加: