C++言語機能(C++11/14/17/20)の中で、特に使いそうなもの

しばらくぶりに、C++のプログラム開発を本格的に行うことになりそうなため、使いそうな拡張言語機能の確認をしています。

cpprefjp – C++日本語リファレンス

拡張言語機能について、日本語で良くまとめられているサイト。

C++言語仕様のバージョンアップで、何が行われてきたか状況把握できます。

以下は、それぞれのバージョンにおける拡張で、直近使うことになりそうなものを、できるだけ少ない数としてピックアップしています。知らなくても使うことになりそうな拡張は、あえてピックアップしていません。

また、機能の非推奨化と削除については、転載させて頂いています。

C++11

auto型推論
decltype式の型を取得
範囲for文配列やコンテナといった範囲を表すオブジェクトを、簡潔に走査する
初期化子リスト波括弧による初期化をユーザー定義する。vector<int> v = {1, 2, 3};など。
一様初期化コンストラクタの呼び出しを、波カッコで行う。T x {a, b, c};
右辺値参照・ムーブセマンティクス右辺値によるオーバーロード、およびそれによるリソースの所有権移動
ラムダ式関数オブジェクトをその場に書く
noexcept関数の例外指定、例外を投げる可能性のある式かbool値を返す演算子
constexpr定数式
nullptrヌルポインタを表すポインタリテラル
インライン名前空間ネストした名前空間に、透過的にアクセスする
ユーザー定義リテラルリテラルのサフィックスをユーザー定義する
関数のdefaultdelete宣言自動定義される特殊関数の制御
移譲コンストラクタコンストラクタから他のコンストラクタに処理を移譲する
非静的メンバ変数の初期化メンバ変数を、宣言と同時に初期値指定する
継承コンストラクタ基底クラスのコンストラクタを継承する
overridefinalメンバ関数のオーバーライド指定、および派生クラスでのオーバーライドの禁止を指定する
スコープを持つ列挙型強い型付けとスコープを持つ列挙型の導入と、それにともなって従来の列挙型を機能拡張
共用体の制限解除共用体のメンバ変数として、クラスオブジェクトを持てるようにする
extern templateテンプレートのインスタンス化を抑止する
スレッドローカルストレージスレッドごとに異なる静的記憶域に保持される変数
ブロックスコープを持つstatic変数初期化のスレッドセーフ化関数ローカルで定義したstatic変数の初期化を、スレッドセーフにする
戻り値の型を後置する関数宣言構文戻り値の型を後ろに書けるようにすることで、パラメータオブジェクトを戻り値型の文脈で使用できるようにする
コンパイル時アサートコンパイル時に条件式が真であることを表明する
生文字列リテラル文字列リテラルにRプレフィックスを付けることで、エスケープシーケンスを無視する
UTF-8文字列リテラルcharの文字列をUTF-8エンコーディングするプレフィックス
属性構文[[attr]]構文による、クラス、関数、変数の属性指定
alignasアライメントを指定する
入れ子名の指定にグローバルスコープ::を付加することを許可struct ::A {};のように入れ子名を指定する際にグローバルスコープから指定できるようになった
宣言時に要素数を指定した配列オブジェクトの、定義時の要素数を規定staticメンバやexternとして宣言した配列を定義した際、宣言時に指定した要素数として定義されることが規定された
sizeof演算子にクラスの非静的メンバを、オブジェクトを作らずに指定できるようにするsizeof(T::data_member)のように指定して非静的メンバのサイズを取得する
可変引数マクロマクロで任意の数の引数を受け取る
事前定義識別子__func__現在いる関数名が格納されている識別子
std::array固定長配列クラスstd::arrayを追加
emplace()
emplace_back()
emplace_front()
要素追加のためのメンバ関数として、クラステンプレートのパラメータTのコンストラクタ引数を受け取り、一時オブジェクトの生成コストを減らせるものが追加された。これらは、以下のように命名されたメンバ関数である:emplace()emplace_back()emplace_front()
初期化子リスト初期化子リストでコンテナを初期化できるようになった
std::next()
std::prev()
イテレータを進める関数std::next()、イテレータを逆に進める関数std::prev()を追加
std::move_iterator要素をムーブするイテレータとして、std::move_iteratorクラスを追加
std::begin()
std::end()
先頭イテレータと末尾イテレータを取得する非メンバ関数として、std::begin()std::end()を追加
std::all_of()
std::any_of()
std::none_of
範囲が特定の条件を満たしているか調べる、std::all_of()std::any_of()std::none_ofを追加
std::copy_n()指定された数の要素をコピーするstd::copy_n()を追加
std::copy_if()条件を満たす要素のみをコピーするstd::copy_if()を追加
std::is_sorted()範囲がソート済みか調べるstd::is_sorted()を追加
std::min()
std::max()
2つの値の最小値を取得するstd::min()、最大値を取得するstd::max()に、初期化子リストによる可変引数版を追加
std::minmax()
std::minmax_element()
最小値と最大値を同時に取得する関数std::minmax()std::minmax_element()を追加
std::shared_ptr
std::unique_ptr
スマートポインタの実装として、所有権共有方式のstd::shared_ptrクラと所有権専有方式のstd::unique_ptrクラスを追加
std::u16string
std::u32string
UTF-16の文字列型std::u16string、UTF-32の文字列型std::u32stringを追加
std::to_string()
std::to_wstring()
数値から文字列オブジェクトに変換する関数として、std::to_string()std::to_wstring()を追加
std::stoi()
std::stof()
文字列オブジェクトから数値に変換する、std::stoi()std::stof()といった関数を追加
std::function関数ポインタと関数オブジェクトを統一的に扱えるクラスstd::functionを追加
std::bind()関数の引数を束縛して部分適用する関数std::bind()を追加
std::mem_fn()メンバ関数ポインタを関数オブジェクトにアダプトする関数std::mem_fn()を追加
std::hashハッシュ表コンテナの追加にともない、オブジェクトのハッシュ値を計算する
関数オブジェクトstd::hashクラスを追加
std::threadスレッドを管理するクラスstd::threadを追加
std::mutex
std::recursive_mutex
スレッド間での排他制御を行うミューテックスの実装であるstd::mutexクラス、
std::recursive_mutexクラス等を追加
std::lock_guard
std::unique_loc
ミューテックスの所有権放棄を自動的に行うためのクラスstd::lock_guard
std::unique_lockを追加
std::call_once()スレッドセーフに一度だけ処理を呼び出す関数、std::call_once()を追加
std::condition_variable
std::condition_variable_any
条件変数の実装であるstd::condition_variableクラス、std::condition_variable_anyクラスを追加
std::future
std::promise
Futureデザインパターンをサポートするstd::futureクラス、std::promiseクラス、およびその補助機能を追加
<atomic>アトミック操作のライブラリ<atomic>を追加
std::move()ムーブセマンティクスのために、左辺値を右辺値に変換する関数std::move()を追加
std::tupleタプルの実装であるstd::tupleクラスを追加
<chrono>時間ユーティリティライブラリ<chrono>を追加
<type_traits>型特性ライブラリ<type_traits>を追加
<system_error>OSのエラー値を扱うライブラリ<system_error>を追加
<regex>正規表現ライブラリ<regex>を追加
<random>乱数ライブラリ<random>を追加
<cstdint>ビット幅規定の整数型ライブラリである<cstdint>を追加
C++11
機能の非推奨化 (C++11)

  • registerキーワードを非推奨化。コンパイラに使われなくなった最適化用の機能を非推奨化
  • 従来のスマートポインタauto_ptrクラスを、非推奨とする
  • 従来の関数オブジェクトアダプタstd::unary_functionstd::binary_functionstd::mem_fun()std::mem_fun_ref()等を非推奨とする
  • 従来の関数バインダstd::bind1ststd::bind2nd等を非推奨とする


C++14

[[deprecated]]属性非推奨の機能であることを示す属性
std::make_unique()
std::make_unique()
std::unique_ptrを生成するヘルパ関数std::make_unique()を追加
std::exchange()2つの値を入れ替える関数std::exchange()を追加
リテラル演算子sstd::basic_stringリテラル演算子sを追加

"hello"sは、文字コード未規定のstd::stringオブジェクトを表すリテラル

L"hello"sは、文字コード未規定のstd::wstringオブジェクトを表すリテラル

u8"hello"sは、UTF-8文字コードのstd::stringオブジェクトを表すリテラル

u"hello"sは、UTF-16文字コードのstd::u16stringオブジェクトを表すリテラル

U"hello"sは、UTF-32文字コードのstd::u32stringオブジェクトを表すリテラル
各時間単位を表すリテラルstd::chrono::durationの、各時間単位を表す、以下のリテラルを追加

ナノ秒単位を表すnsリテラル
マイクロ秒単位を表すusリテラル
ミリ秒単位を表すmsリテラル
秒単位を表すsリテラル
分単位を表すminリテラル
時単位を表すhリテラル
<shared_mutex>Readers-writer lockと呼ばれる、書き込みを行うユーザーが1人、読み込みを行うユーザーが複数いる状況で効率的に振る舞うミューテックスの実装として、<shared_mutex>ヘッダを追加
C++14

C++17

インライン変数inline指定をすることで翻訳単位を跨いでひとつのオブジェクトになる変数を定義する
構造化束縛組・タプル・配列を展開して変数定義する
[[nodiscard]]属性戻り値を捨ててはならないことを指定する
if文とswitch文の条件式と初期化を分離if (init; condition)のように初期化と条件式を分けて記述できるようにする
if constexprif constexpr(cond)とすることで、そのif文はコンパイル時に処理される
入れ子名前空間の定義namespace A::B {}のように、入れ子の名前空間を簡単に定義できるようにする
例外仕様を型システムの一部にする関数の型に例外仕様が含まれるようにする
非推奨だった古い例外仕様を削除throwキーワードによる例外仕様を削除。throw()は残る
__has_includeインクルードするファイルが存在するかを確認する
非推奨だったregisterキーワードを削除コンパイラから単に無視されていたregisterキーワードを削除。予約語は残
<filesystem><filesystem>ヘッダを新設し、ファイルシステムライブラリを追加。ファイル、ディレクトリなどを扱う
並列実行のオプションを追加<algorithm><numeric>のアルゴリズムに、並列実行のオプションを追加
<any><any>ヘッダを新設し、なんでも代入できるanyクラスを追加
<memory_resource>多相アロケータとメモリプール。<memory_resource>が新設され、アロケートする型を規定しないアロケータと、それを利用したメモリプールの仕組みが導入される
C++17
機能の削除 (C++17)

  • C++11から非推奨だった古いスマートポインタであるauto_ptrを削除。代わりにshared_ptrunique_ptrを使用すること
  • C++14から非推奨だった配列をランダムに入れ替えるrandom_shuffle()関数を削除。代わりにshuffle()を使用すること
  • C++11から非推奨だったthrowキーワードによる古い例外仕様に関連する、以下のライブラリ機能を削除する
  • C++11から非推奨だった古い<functional>の機能を削除
    • 引数を束縛するbind1st()関数、bind2nd()関数、binder1stクラス、binder2ndクラスを削除。代わりにbind()関数やラムダ式を使用すること
    • 関数ポインタから関数オブジェクトに変換するためのptr_fun()関数、pointer_to_unary_functionクラス、pointer_to_binary_functionクラスを削除。first_argument_typesecond_argument_typeといった型が必要なくなったため、これらの機能は必要なくなった
    • メンバ関数から関数オブジェクトへの変換をするためのmem_fun()関数、mem_fun_ref()関数、mem_fun_tクラス、mem_fun1_tクラス、mem_fun_ref_tクラス、mem_fun1_ref_tクラス、const_mem_fun_tクラス、const_mem_fun1_tクラス、const_mem_fun_ref_tクラス、const_mem_fun1_ref_tクラスを削除。代わりにmem_fn()bind()関数やラムダ式を使用すること
  • functionクラスのアロケータサポートを削除。コンパイラが実装していなかったり、不完全な実装だったりしていた
  • C++98から非推奨だったiostreamのエイリアスを削除
    • ios_base::io_stateの代わりにios_base::iostateを使用すること
    • ios_base::open_modeの代わりにios_base::openmodeを使用すること
    • ios_base::seek_dirの代わりにios_base::seekdirを使用すること
    • ios_base::streamoffの代わりに、char_traits<CharT>::off_typeもしくはbasic_ios<CharT>::off_typeを使用すること (<iosfwd>で定義されているstd::streamoffは残る)
    • ios_base::streamposの代わりに、char_traits<CharT>::pos_typeもしくはbasic_ios<CharT>::pos_typeを使用すること (<iosfwd>で定義されているstd::streamposは残る)
    • basic_streambuf::stossc()メンバ関数を削除。sbumpc()の単なる別名
    • ios_baseクラスの別名型が削除されることにともない、それらの型をパラメータにとるオーバーロードを削除
    • ios_baseクラスの別名型が削除されることにともない、それらの型をパラメータにとる関数が削除
機能の非推奨化 (C++17)

  • std::iteratorクラスを非推奨化。このクラスを使用しても、イテレータ定義は簡単にならなかった
  • C++11でallocator_traitsクラスが導入されたことで不要になった、allocatorの以下のメンバを非推奨化:
  • C++11でallocator_traitsクラスが導入されたことで不要になった、要素型を再束縛するためのallocator<void>特殊化を非推奨化
  • constexprの機能拡張によって扱える型が増えている。将来的にほとんどの型がconstexprで扱えるようになるため、constexprで扱える型の分類であるis_literal_type型特性を非推奨化
  • 一時的なメモリ確保のためのstd::get_temporary_buffer()関数とstd::return_temporary_buffer()関数を非推奨化。これらは関数内での一時的なメモリ確保のために、最適化されたメモリ確保の仕組みを提供することを期待して定義されたが、実際にはどの実装も特別視せず、それゆえに便利に使われてはこなかった。将来的にスタックからのメモリ確保をする機能を作る予定だが、これらの関数は例外安全性やRAIIが考慮されていないため、これらの関数の実装・仕様のみを入れ替えるような改訂はできない
  • raw_storage_iteratorクラスを非推奨化。アロケータとの連携ができず、限られた用途にしか使用できなかった
  • not_fn()の追加にともない、古くなった以下の機能を非推奨化:
  • デバッグ用途にしか使用しない、shared_ptr::unique()を非推奨化
  • result_ofを非推奨化。代わりにinvoke_resultを使用すること
  • <codecvt>と関連する機能を非推奨化。適切なエラーハンドリングの方法がなかったため、セキュリティ上攻撃の可能性があった
  • memory_order_consumeを一時的に非推奨化。「その定義が現実に即していない」「acquire/releaseより弱いから使いにくい」といった理由から、より良い定義に変更するまでの間、非推奨とする
  • uncaught_exceptions()の追加にともない、古くなったuncaught_exception()を非推奨化

C++20

初期化式をともなう範囲for文範囲for文スコープで使用する変数の初期化のための構文を追加
確率が高い分岐と低い分岐を伝える属性 [[likely]][[unlikely]]条件分岐の最適化ヒントを与える属性
入れ子名前空間定義でのインライン名前空間namespace ns1::inline ns2::ns3 {}のように、入れ子名前空間を定義する式にインライン名前空間の指定を含められるようにする
モジュールヘッダファイル・ソースファイル、インクルードに変わる仕組みとしてモジュールを導入する
コルーチン関数実行を中断・再開する仕組みとしてコルーチンを導入する
<source_location>ソースコードの位置を取得するライブラリとして<source_location>を追加
std::make_unique_for_overwrite()
std::make_shared_for_overwrite()
std::allocate_shared_for_overwrite()
スマートポインタをデフォルト初期化で構築するヘルパ関数として、std::make_unique_for_overwrite()std::make_shared_for_overwrite()std::allocate_shared_for_overwrite()を追加
std::to_address()ポインタを生ポインタに変換するstd::to_address()を追加
C++20
機能の削除 (C++20)

throw()による例外送出しない指定を削除代わりにnoexceptを使用すること
ユーザー宣言したコンストラクタを持つクラスの集成体初期化を禁止コンストラクタがdelete宣言されているクラスを、集成体初期化によってコンストラクタ呼び出しを回避して構築できてしまっていた技法を禁止
  • C++11でallocator_traitsクラスが導入されたことでC++17から非推奨化されていた、allocatorの以下のメンバを削除:
  • 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から非推奨化されていた以下の機能を削除:
  • 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>を削除
機能の非推奨化 (C++20)

PODを非推奨化
[=]によるthisの暗黙のキャプチャを非推奨化コピーのデフォルトキャプチャでは、thisポインタをキャプチャされなくする
添字演算子内でのカンマ演算子の使用を非推奨化ar[i, j]を非推奨化。ar[(i, j)]はOK
  • 一貫比較非機能によって比較演算子の定義が容易になったため、不要になった演算子の簡潔定義機能であるstd::rel_opsを非推奨化
  • std::basic_string::reserve()メンバ関数が、メモリの縮小をしなくなったため、デフォルト引数0を非推奨可
  • std::atomicクラスとstd::atomic_flagクラスのデフォルトコンストラクタが値初期化するようになったため、不要になった以下のアトミックオブジェクトの初期化機能を非推奨化:

C++23

当面先の話

機能の非推奨化 (C++23)

std::algined_storagestd::aligned_unionを非推奨化。これらの機能は未定義動作を引き起こし、間違った保証が行われ、よくないAPI設計が行われていたため、非推奨となる。

標準ライブラリ

コンパイラの実装状況

参考

プログラム開発

Posted by iwadjp