概要
C++20とは、2020年中に改訂され、ISO/IEC 14882:2020で標準規格化されたC++バージョンの通称である。
このバージョンは、策定中はC++2aと呼ばれることがあった。「202a年にリリースされる」という伏せ字として「a」が使われているが、3年周期に次のバージョンが策定されることが決まっているため、伏せ字になっている年数がずれることはない。
言語機能
クラス
| 言語機能 | 説明 |
|---|---|
<=>/==による比較演算子の自動定義 |
三方比較演算子によって比較演算子の自動生成を行うようにする |
| ビットフィールドのメンバ変数初期化 | ビットフィールドメンバ変数のデフォルト値を設定する構文を追加する |
関数を条件付きでexplicitにする構文を追加 |
explicit(true)のようにexplicitに真理値パラメータを指定できるようにする |
const修飾されたメンバポインタの制限を修正 |
.*演算子での左辺値のconstメンバ関数呼び出しを許可する |
デフォルトのコピーコンストラクタと非constなコンストラクタが衝突する問題を修正 |
非constなオブジェクトをとるコンストラクタを定義すると、そのクラスをラップしたクラスのコピーコンストラクタが不適格になってしまう問題を修正 |
| 特殊化のアクセスチェック | |
空オブジェクトに対する最適化を支援する属性[[no_unique_address]] |
[[no_unique_address]]属性を導入し、空の型のオブジェクトをほかのオブジェクトと共有する最適化を許可する |
| friend指定された関数内から構造化束縛を使用して非公開メンバ変数にアクセスすることを許可 | 構造化束縛の仕様として公開メンバ変数のみを取り出せるようになっていたが、friend指定された関数からは非公開メンバ変数にもアクセスできるようにする |
| 構造化束縛がカスタマイゼーションポイントを見つけるルールを緩和 | 非テンプレートのget()メンバ関数が見つかった場合は、非メンバ関数のget()を探しにいく |
| 抽象型のチェック | 関数の宣言段階では、パラメータおよび戻り値型が抽象型かどうかをチェックしないようにする |
可変長データを扱うクラスの効率的なdelete |
クラスのdelete演算子が呼び出される前にデストラクタが呼ばれないようにするオプションを追加 |
| 条件付きで特殊メンバ関数をトリビアルに定義するように | 制約によってトリビアルな特殊メンバ関数と非トリビアルな特殊メンバ関数をオーバーロードできるようにする |
| 未初期化領域への暗黙的なオブジェクト構築 | 未初期化領域の利用時に自動的にトリビアルな型のオブジェクトを構築する |
列挙型
| 言語機能 | 説明 |
|---|---|
| スコープ付き列挙型のusing宣言 | using enum EnumType;もしくはusing EnumType::enumeratorとすることで、列挙値のスコープ指定を省略できるようにする |
変数
| 言語機能 | 説明 |
|---|---|
| 指示付き初期化 | 波カッコによる集成体初期化でメンバ名を指定して初期化できるようにする |
| 構造化束縛を拡張して通常の変数宣言のように使用できるようにする | 記憶域指定子としてstaticとthread_localの指定を許可 |
| 丸カッコの値リストからの集成体初期化を許可 | T x{1, 2, 3};と同様にT x(1, 2, 3);でも集成体初期化できるようにする |
new式での配列要素数の推論 |
double* p = new double[]{1,2,3};を許可 |
| 要素数不明の配列への変換を許可 | 要素数が判明している配列から、要素数が不明の配列への変換を許可 |
ポインタからboolへの変換を縮小変換とする |
ポインタからbool値への変換を縮小変換と規定することで、意図しない変換を防止する |
整数
| 言語機能 | 説明 |
|---|---|
| 符号付き整数型が2の補数表現であることを規定 | 符号付き整数型のビット表現を2の補数に規定する |
文字列
| 言語機能 | 説明 |
|---|---|
UTF-8エンコーディングされた文字の型としてchar8_tを追加 |
UTF-8エンコードされた文字かどうかでオーバーロード・特殊化をできるようにする |
char16_tとchar32_tの文字・文字列リテラルを、文字コードUTF-16/32に規定 |
__STDC_UTF_16__、__STDC_UTF_32__の定義に関係なく、char16_t、char32_tのリテラルをUTF-16/32文字コードに規定する |
関数
| 言語機能 | 説明 |
|---|---|
[[nodiscard]]属性に理由となる文字列を付加できるようにする |
関数の戻り値を無視してはならない理由を関数宣言に持たせ、警告メッセージに役立てる |
[[nodiscard]]をコンストラクタのオーバーロードごとに付加できるようにする |
リソース確保するコンストラクタにのみ[[nodisacrd]]を付加できるようにする |
制御構文
| 言語機能 | 説明 |
|---|---|
| 初期化式をともなう範囲for文 | 範囲for文スコープで使用する変数の初期化のための構文を追加 |
| 範囲for文がカスタマイゼーションポイントを見つけるルールを緩和 | begin()/end()メンバ関数のどちらかが見つからなかった場合に非メンバ関数のbegin()/end()を探しにいく |
確率が高い分岐と低い分岐を伝える属性 [[likely]], [[unlikely]] |
条件分岐の最適化ヒントを与える属性 |
テンプレート
| 言語機能 | 説明 |
|---|---|
| コンセプト | テンプレートパラメータに対する制約を行う |
| autoパラメータによる関数テンプレートの簡易定義 | ジェネリックラムダと同様、関数パラメータの型をautoにすることで簡易的に関数テンプレートを定義できるようにする |
型の文脈でtypenameの省略を許可 |
型しか現れない文脈では、依存名を解決するためのtypenameキーワードを省略できるようにする |
| 非型テンプレートパラメータとしてクラス型を許可する | 定数式として使用できる型を広く非型テンプレートパラメータとして使用できるようにする |
| 関数テンプレートに明示的に型指定した場合にADLで見つからない問題を修正 | 名前空間内の関数テンプレートをテンプレート引数指定かつ非修飾・ADLで正しく呼び出せるよう修正 |
| 集成体クラステンプレートのテンプレート引数推論 | クラステンプレートのテンプレート引数推論はコンストラクタ引数から推論されるが、集成体初期化からも推論できるようにする |
| エイリアステンプレート経由でのクラステンプレートのテンプレート引数推論 | エイリアステンプレートからクラステンプレートのテンプレート引数を推論できるようにする |
定数式
| 言語機能 | 説明 |
|---|---|
| 評価されない文脈での定数式評価によって特殊メンバ関数がインスタンス化されることを規定 | sizeofやdecltypeなどの評価されない文脈において定数式評価を行った場合に、ムーブコンストラクタのような特殊メンバ関数が定義されることを規定 |
| 定数式からの仮想関数の呼び出しを許可 | 仮想関数にconstexprを付けられない制限を解除 |
定数式でのdynamic_cast、多態的なtypeidを許可 |
定数式での動的多態を許可 |
| constexpr関数内でのtry-catchブロックを許可 | constexpr関数内でtry-catchブロックを書けるようにする |
常に定数式評価するconsteval |
constevalキーワードを追加し、常に定数式評価されるよう指定できるようにする |
| 定数式内での共用体のアクティブメンバの変更を許可 | 共用体メンバの書き換えを定数式内で行えるようにする |
| constexpr関数内でのトリビアルなデフォルト初期化を許可 | constexpr関数内でのデフォルト初期化を許可し、未初期化値を読むことのみ禁止する |
| constexpr関数内で未評価のインラインアセンブリを許可することによる組み込み関数のconstexpr有効化 | コンパイル時に評価されない場合にconstexpr関数にasm定義を含めることを許可 |
コンパイル時初期化を強制するconstinitキーワードを追加 |
初期化のみコンパイル時におわらせたい場合に使用する |
可変サイズをもつコンテナのconstexpr化 |
constexpr記憶域をもつメモリアロケータの存在を考慮することで、可変サイズをもつコンテナをコンパイル時に使用できるようにする |
ラムダ式
| 言語機能 | 説明 |
|---|---|
| ジェネリックラムダのテンプレート構文 | ジェネリックラムダでテンプレートパラメータを定義できるようにする |
ラムダ式のキャプチャとして[=, this]を許可する |
デフォルトコピーキャプチャとthisポインタのコピーキャプチャを両方指定できるようにする |
| 暗黙のラムダキャプチャを簡略化 | ラムダ式のキャプチャに関する仕様整理 |
| 状態を持たないラムダ式を、デフォルト構築可能、代入可能とする | キャプチャしていないラムダ式をデフォルト構築・代入可能にする |
| 評価されない文脈でのラムダ式 | 評価されない文脈でもラムダ式を書くことができるようにする |
| ラムダ式の初期化キャプチャでのパック展開を許可 | [...args = std::move(args)]のようなキャプチャを許可 |
| 構造化束縛した変数の参照キャプチャを許可 | 構造化束縛をした変数は特殊な扱いのためラムダ式で参照キャプチャできない規定となっていたがこれを許可する |
名前空間
| 言語機能 | 説明 |
|---|---|
| 入れ子名前空間定義でのインライン名前空間 | namespace ns1::inline ns2::ns3 {}のように、入れ子名前空間を定義する式にインライン名前空間の指定を含められるようにする |
モジュール化
| 言語機能 | 説明 |
|---|---|
| モジュール | ヘッダファイル・ソースファイル、インクルードに変わる仕組みとしてモジュールを導入する |
並行・並列処理
| 言語機能 | 説明 |
|---|---|
| コルーチン | 関数実行を中断・再開する仕組みとしてコルーチンを導入する |
プリプロセッサ
| 言語機能 | 説明 |
|---|---|
| 可変引数が空でない場合のトークン置換 | プリプロセッサの置換で可変引数が空の場合に余計なカンマが付いてしまう問題に対処 |
機能の非推奨化
| 言語機能 | 説明 |
|---|---|
ほとんどのvolatileを非推奨化 |
volatileの有用な機能のみを残し、効果が疑わしい、または壊れている機能を非推奨化する |
| PODを非推奨化 | PODという用語を非推奨化する |
[=]によるthisの暗黙のキャプチャを非推奨化 |
コピーのデフォルトキャプチャでは、thisポインタのキャプチャを非推奨化する |
| 添字演算子内でのカンマ演算子の使用を非推奨化 | ar[i, j]を非推奨化。ar[(i, j)]はOK |
| 列挙値から算術型への暗黙変換を非推奨化 | 列挙値への算術演算で算術型に暗黙変換される仕様を非推奨とする |
| 組み込み配列の比較を非推奨化 | 組み込み配列同士の比較演算を非推奨とする |
機能の削除
| 言語機能 | 説明 |
|---|---|
throw()による例外送出しない指定を削除 |
代わりにnoexceptを使用すること |
| ユーザー宣言したコンストラクタを持つクラスの集成体初期化を禁止 | コンストラクタがdelete/default宣言されているクラスを、集成体初期化によってコンストラクタ呼び出しを回避して構築できてしまっていた技法を禁止 |
小さな変更
| 言語機能 | 説明 |
|---|---|
| 更新された定義済みマクロ | 標準規格で定義されたマクロの更新 |
| Unicode標準への参照を更新 | 標準C++からISO/IEC 10646への参照を更新する |
| 属性の名前空間を予約 | 将来の使用のために属性の名前空間を予約 |
ライブラリ更新の概要
新ライブラリ
- バージョン情報ライブラリとして
<version>を追加。ここでは、実装依存の情報 (バージョンやリリース日付など) が標準ライブラリの実装によって定義される <chrono>ライブラリに、カレンダーとタイムゾーンの機能を拡張- 任意のシーケンスの部分シーケンスを参照するライブラリとして
<span>を追加 - 文字列フォーマットライブラリとして
<format>を追加 - 出力ストリームを同期するライブラリとして
<syncstream>を追加 - 三方比較ライブラリとして
<compare>を追加 - 数値ライブラリとして
<numbers>を追加。数学定数が定義される - ビット操作ライブラリとして
<bit>を追加- Strict Aliasing規則に抵触しないビットレベルの再解釈キャストである
std::bit_cast()関数を追加 - 1ビットだけ立っている値をもっているかを判定する
std::has_single_bit()関数を追加 - 整数値を2の累乗値に切り上げる
std::bit_ceil()関数、整数値を2の累乗値に切り下げるstd::bit_floor()関数を追加 - 値を表現するために必要なビット幅を求める
std::bit_width()関数を追加 - 循環ビットシフトを行う
std::rotl()とstd::rotr()を追加 - 連続した0もしくは1のビットを数える
std::countl_zero()、std::countl_one()、std::countr_zero()、std::countr_one()、および立っているビットを数えるstd::popcount()を追加 - エンディアンを表す列挙型として
std::endianを追加
- Strict Aliasing規則に抵触しないビットレベルの再解釈キャストである
- 型制約のための要件ライブラリとして
<concepts>を追加 - 言語機能であるコルーチンを制御するライブラリとして
<coroutine>を追加 - スレッドの実行を停止させるメカニズムとして
<stop_token>を追加し、停止に対応したスレッドクラスとして<thread>にstd::jthreadクラスを追加 - 軽量な同期プリミティブであるセマフォのライブラリとして
<semaphore>を追加 - スレッド調整メカニズムとして、ラッチライブラリの
<latch>、バリアライブラリの<barrier>を追加 - イテレータの組ではなく、コンテナや配列、部分的なコンテナなどを扱う範囲ライブラリとして
<ranges>を追加- 既存のイテレータの組を扱うアルゴリズムは、
std::ranges名前空間に範囲版アルゴリズムが追加される
- 既存のイテレータの組を扱うアルゴリズムは、
- ソースコードの位置を取得するライブラリとして
<source_location>を追加
取り決め
std名前空間以下の関数テンプレートをユーザーが特殊化することを禁止する (参照 : P0551R3)
コンテナ
- 連想コンテナに、要素がコンテナに含まれているかを判定する
contains()メンバ関数を追加 - 順序付き連想コンテナと同様に、非順序連想コンテナの検索処理で、一時オブジェクトが生成されるコストを抑える拡張を追加。キー等値比較を行う関数オブジェクトとハッシュ計算を行う関数オブジェクトの両方に
is_transparentが定義されていれば、透過的な検索が使用できる。std::hashクラスのページを参照 - 各コンテナの非メンバ関数として、要素を削除する
std::erase()関数とstd::erase_if()関数を追加 std::forward_listとstd::listのメンバ関数remove()、remove_if()、unique()の戻り値型を、voidからContainer::size_typeに変更std::arrayクラスの比較演算子、fill()メンバ関数、swap()メンバ関数、swap()非メンバ関数にconstexprを追加。このクラスのメンバ関数はすべてconstexprに対応した- 組み込み配列を
std::arrayに変換する関数としてstd::to_array()を追加 <iterator>に、符号付き整数としてコンテナの要素数を取得するstd::ssize()関数を追加std::allocator、およびstd::vectorとstd::basic_stringをconstexpr対応
アルゴリズム
<algorithm>の多くの関数にconstexprを追加<algorithm>に、要素位置をシフトするstd::shift_left()、std::shift_right()を追加<algorithm>に三方比較による辞書順比較アルゴリズムstd::lexicographical_compare_three_way()を追加- 数値とポインタの中点を求める関数として、
<numeric>にstd::midpoint()関数を追加 - 浮動小数点数を線形補間する関数として、
<cmath>にstd::lerp()関数を追加 <numeric>の数値計算アルゴリズムをムーブに対応<numeric>の数値計算アルゴリズムにconstexprを追加
イテレータ
std::back_insert_iteratorクラス、std::front_insert_iteratorクラス、std::insert_iteratorクラスのコンストラクタ、代入演算子、間接参照演算子、インクリメント演算子、およびstd::back_inserter()、std::front_inserter()、std::inserter()にconstexprを追加。これらのクラスのメンバ関数はすべてconstexprに対応した
関数オブジェクト
std::reference_wrapperクラス、std::ref()関数、std::cref()関数のテンプレートパラメータT型に不完全型を指定することを許可- メンバ関数の部分適用を簡単にするために、プレースホルダーの指定なく引数を先頭から順に束縛する
std::bind_front()関数を追加 std::invoke()、std::reference_wrapperの各操作、std::not_fn()、std::bind()、std::mem_fn()をconstexpr対応- コンセプトの導入にともない、
<functional>に、受け取った値をそのまま返す関数オブジェクトstd::identityを追加
文字列
std::basic_stringクラスとstd::basic_string_viewクラスに、先頭の部分文字列を判定するstarts_with()メンバ関数、末尾の部分文字列を判定するends_with()メンバ関数を追加std::basic_string::reserve()メンバ関数の、メモリの縮小機能を削除し、伸長のみとする。std::char_traitsクラスのmove()、copy()、assign()静的メンバ関数にconstexprを追加
並行・並列処理
std::atomicクラスとstd::atomic_flagクラスのデフォルトコンストラクタが、値初期化するよう動作変更。これまではC言語との互換性のために未初期化となっていた<memory>に、std::atomicクラスのstd::shared_ptrとstd::weak_ptrに対する特殊化を追加std::atomicクラスの浮動小数点数型に対する特殊化を追加- アトミッククラスに対するブロッキング同期の機能として
wait()、notify_one()、notify_all()を追加 - ロックフリーであることが保証されたアトミック整数型の別名として
atomic_signed_lock_freeとatomic_unsigned_lock_freeを追加 std::memory_orderの列挙子にスコープをもたせたstd::atomic_flagクラスに、bool値を読み込むメンバ関数test()を追加- 非アトミックなオブジェクトにアトミック操作を適用するためのクラス
std::atomic_refを追加 - ベクトル化の実行ポリシーとして、
<execution>にstd::execution::unsequenced_policy型とstd::execution::unseqタグを追加
入出力
- 同期ストリームの追加にともなって、
<ostream>に、同期ストリーム関係の出力マニピュレータを追加 operator>>(basic_istream&, CharT*)をoperator>>(basic_istream&, CharT (&)[N])に修正operator<<に、wchar_t(char版のみ)、char8_t、char16_t、char32_tのdelete宣言を追加std::istream_iteratorについて、要件の書き方を整理し、振る舞いをより明確化std::basic_stringbuf、std::basic_istringstream、std::basic_ostringstreamクラスに、アロケータを伝播させるためのインタフェースを追加
スマートポインタ
std::make_shared()とstd::allocate_shared()を配列に対応- スマートポインタをデフォルト初期化で構築するヘルパ関数として、
std::make_unique_for_overwrite()、std::make_shared_for_overwrite()、std::allocate_shared_for_overwrite()を追加 - ポインタを生ポインタに変換する
std::to_address()を追加 std::pointer_traits::pointer_to()関数にconstexprを追加
メモリ
<memory>に、Nバイトアライメントされたポインタであることをコンパイラに伝えるstd::assume_aligned()関数を追加<memory>に、uses allocator構築をサポートするユーティリティ関数として、std::uses_allocator_construction_args()、std::make_obj_using_allocator()、std::uninitialized_construct_using_allocator()を追加std::pmr::polymorphic_allocatorに、以下の変更を追加:- クラステンプレートのデフォルトテンプレート引数を
std::byte型とした void*のバイト列をメモリ確保するallocate_bytes()、解放するdeallocate_bytes()メンバ関数を追加- 指定した型のメモリを確保する
allocate_object()、解放するdeallocate_object()を追加 - 指定した型のメモリ確保と構築をする
new_object()、破棄と解放をするdelete_object()を追加
- クラステンプレートのデフォルトテンプレート引数を
ユーティリティ
<utility>に、符号付き整数と符号なし整数の安全な比較関数として、以下を追加:std::swap()関数にconstexprを追加std::exchange()関数にconstexprを追加std::complexクラスをconstexprに対応std::pairクラスのコンストラクタ、代入演算子、swap()メンバ関数、swap()非メンバ関数にconstexprを追加。このクラスのメンバ関数はすべてconstexprに対応したstd::tupleクラスのコンストラクタ、代入演算子、swap()メンバ関数、swap()非メンバ関数にconstexprを追加。このクラスのメンバ関数はすべてconstexprに対応した
ファイルシステム
std::filesystem::create_directory()とstd::filesystem::create_directories()の仕様が直感的ではなく、すでにディレクトリが存在している場合にエラーとなっていた。C++20ではその状況ではエラーにならないようにする (エラーではなくfalseが返る)
型特性
<type_traits>に、constexpr関数が定数式評価されたかを判定する特殊な関数std::is_constant_evaluated()を追加<type_traits>に、型のCV修飾と参照を除去する型特性クラスとしてstd::remove_cvrefを追加<type_traits>に、受け取った型をそのまま返すstd::type_identityを追加<type_traits>に、例外送出せずに暗黙の型変換が可能かを判定するstd::is_nothrow_convertibleを追加<type_traits>に、要素数が判明している配列型かを判定するstd::is_bounded_array、要素数が不明な配列型かを判定するstd::is_unbounded_arrayを追加<type_traits>に、レイアウト互換性、ポインタ相互交換可能性を判定する以下の型特性を追加:- 2つの型にレイアウト互換があるかを判定する
std::is_layout_compatible - 2つのメンバポインタが互換な共通位置にあるかを判定する
std::is_corresponding_member() - 基底クラスと派生クラスの間でポインタ相互交換可能かを判定する
std::is_pointer_interconvertible_base_of - メンバポインタとクラスの間でポインタ相互交換可能かを判定する
is_pointer_interconvertible_with_class()
- 2つの型にレイアウト互換があるかを判定する
<type_traits>に、std::reference_wrapper<T>型をT&型に展開するstd::unwrap_reference型特性、std::decay+std::reference_wrapper<T>型の展開をするstd::unwrap_ref_decay型特性を追加
機能の非推奨化
- 一貫比較機能によって比較演算子の定義が容易になったため、不要になった演算子の簡潔定義機能である
std::rel_opsを非推奨化 std::basic_string::reserve()メンバ関数が、メモリの縮小をしなくなったため、デフォルト引数0を非推奨化std::atomicクラスとstd::atomic_flagクラスのデフォルトコンストラクタが値初期化するようになったため、不要になった以下のアトミックオブジェクトの初期化機能を非推奨化:std::shared_ptrのstd::atomic特殊化追加にともない、std::shared_ptrに対する以下のアトミック操作を非推奨化:std::atomic_is_lock_freestd::atomic_loadstd::atomic_load_explicitstd::atomic_storestd::atomic_store_explicitstd::atomic_exchangestd::atomic_exchange_explicitstd::atomic_compare_exchange_weakstd::atomic_compare_exchange_strongstd::atomic_compare_exchange_weak_explicitstd::atomic_compare_exchange_strong_explicit
機能の削除
- C++11で
allocator_traitsクラスが導入されたことでC++17から非推奨化されていた、allocatorの以下のメンバを削除。なお、size_type型とdifference_type型の非推奨は取り消された。pointer型const_pointer型reference型const_reference型rebind型address()メンバ関数allocate()メンバ関数のhintパラメータmax_size()メンバ関数construct()メンバ関数destroy()メンバ関数
- C++11で
allocator_traitsクラスが導入されたことでC++17から非推奨化されていた、要素型を再束縛するためのallocator<void>特殊化を削除 - C++17で非推奨化されていた、
constexprで扱える型の分類であるis_literal_type型特性を削除 - C++17で非推奨化されていた、一時的なメモリ確保のための
std::get_temporary_buffer()関数とstd::return_temporary_buffer()関数を削除 - C++17で非推奨化されていた
raw_storage_iteratorクラスを削除 not_fn()の追加にともない、C++17から非推奨化されていた以下の機能を削除:not1()関数not2()関数unary_negateクラスbinary_negateクラス- 標準関数オブジェクトの
result_type、argument_type、first_argument_type、second_argument_type型
- C++17から非推奨化されていた
shared_ptr::unique()を削除 invoke_resultの追加にともない、C++17から非推奨化されていたresult_ofを削除- C++17での
uncaught_exceptions()の追加にともない、非推奨化していたuncaught_exception()を削除 - C++17で非推奨化されていたC互換ライブラリ
<ccomplex>,<cstdalign>,<cstdbool>,<ctgmath>を削除。また、C++ではなにも定義されないC互換ライブラリ<ciso646>を削除