C++26 とは - 静的リフレクション・契約・std::execution を一次情報で読み解く

C++26 とは - 静的リフレクション・契約・std::execution を一次情報で読み解く

作成日:
読了:13
更新日:
この記事を読む人におすすめPR / Amazonアソシエイト

当サイトは Amazon.co.jp を宣伝しリンクすることで紹介料を得る手段を提供する、Amazonアソシエイト・プログラムの参加者です。価格・在庫はリンク先の最新情報をご確認ください。

概要

C++の次期標準C++26が、2026年3月のISO C++標準化会合(ロンドン近郊Croydon)で最終ドラフトの承認にこぎつけました。目玉は静的リフレクション契約プログラミング(Contracts)、そして非同期・並行処理の統一フレームワークstd::executionの3つです。加えて#embedやpack indexing、未初期化変数の扱いを見直す erroneous behaviour など、地味ですが実務に効く改良も入りました。

本記事はWG21の提案文書(open-std.org)やcppreference、isocpp.org、Herb Sutter氏のトリップレポートといった一次〜準一次情報で裏取りした内容だけをまとめています。まだ標準化プロセスの最終盤という段階なので、「発行済み」「もう使える」と断定できる部分と、そうでない部分を区別しながら読んでください。

C++26 はいまどの段階か(標準化スケジュール)

まず誤解しやすい点を正確にしておきます。2026年3月の会合で承認されたのは最終ドラフト(作業原案)であって、ISOによる正式な規格発行(publish)ではありません

Herb Sutter氏のトリップレポートによると、委員会は技術的な作業を完了し、これから国際承認投票にかけるための最終文書(DIS: Draft International Standard)を作成・編集する段階だと説明されています。本会議での最終採決は賛成114・反対12・棄権3で、全会一致ではありませんでした(反対票は主に後述の契約に対する技術的懸念によるものです)。

NOTE

つまり「C++26の中身は事実上固まった」が正確な表現です。ISOによる正式発行はこの後のDIS投票と編集作業を経て行われる見込みで、本記事執筆時点(2026年7月)ではISO正式発行前と考えるのが妥当です。発行時期の確定日付は未確認です。

なお機能の追加を締め切る feature freeze は2025年6月のソフィア会合で行われ、そこで搭載機能が確定していました。

静的リフレクション

C++26で最も大きな変更が静的リフレクション(提案P2996)です。Herb Sutter氏は「テンプレートの発明以来、C++開発にとって最大級のアップグレード」と表現しています。

ポイントは名前のとおりすべてコンパイル時(static)に完結することです。実行時のオーバーヘッドはなく、C++の「ゼロコスト抽象化」の原則を保ったままメタプログラミングを書けます。

構文の中心は2つです。

  • リフレクション演算子 ^^(見た目から「cat-ears operator」と呼ばれます): 型や関数、メンバなどの構文要素に付けると、std::meta::infoという不透明な型の値を返します。この値がリフレクション情報の実体です。
  • スプライス構文 [: :]: std::meta::infoの値を、ソースコードの文脈へ「注入」して戻します。型として使う場合はtypename[: r :]、テンプレートにはtemplate[: r :]という形になります。

関連するメタ関数群は<meta>ヘッダに置かれます。提案P2996に載っている、enum値を文字列へ変換する例が分かりやすいです。

#include <meta>
#include <string_view>
#include <type_traits>
 
template <typename E>
  requires std::is_enum_v<E>
constexpr std::string_view enum_to_string(E value) {
  if constexpr (std::meta::is_enumerable_type(^^E))
    template for (constexpr auto e : std::meta::enumerators_of(^^E))
      if (value == [:e:])
        return std::meta::identifier_of(e);
  return "<unnamed>";
}

^^Eでenum型を反射し、enumerators_ofで列挙子を取り出し、[:e:]で各列挙子を式へスプライスして比較しています。従来はマクロやコード生成、外部ツールに頼っていた「enumと文字列の対応」を、標準機能だけで書けるようになるわけです。

NOTE

リフレクションのメタ関数はここで挙げた以外にも多数あります。API全体は大きいので、実際に書くときはcppreferenceのstd::metaと提案P2996を参照してください。

契約プログラミング(Contracts)

契約(Contracts)(提案P2900)は、関数の事前条件事後条件アサーションを言語構文として書けるようにする機能です。「この関数は引数がこうであることを前提にする」「戻り値はこうなるはず」という約束をコードに明記できます。

  • pre … 事前条件。関数の引数が初期化された直後、本体に入る前に評価されます。
  • post … 事後条件。関数が正常終了し、ローカル変数が破棄された直後に評価されます。
  • contract_assert … 関数本体の途中に置くアサーション文です。

prepostは「特別な意味を持つ識別子」として、contract_assertはキーワードとして導入されます。書き方のイメージは次のとおりです(構文はcppreference/P2900で確認)。

int shrink(int n)
  pre (n > 0)         // 事前条件: n は正
  post (r : r < n)    // 事後条件: 戻り値 r は n より小さい
{
  contract_assert(n != 0);  // 本体内アサーション
  return n / 2;
}

契約が破られたときにどう振る舞うかは4つの評価セマンティクスで決まります。

  • ignore: 何もチェックしません(実行時コストなし)。
  • observe: 違反を違反ハンドラに通知しますが、ハンドラが正常に戻ればプログラムは続行します。
  • enforce: 違反を報告したうえでプログラムを終了します。
  • quick-enforce: 違反オブジェクトの生成やハンドラ呼び出しを省き、即座に終了します。

WARNING

契約はC++26入りしたものの、委員会内でも価値や設計への技術的懸念が根強く、最終採決が全会一致でなかった理由の一つになっています。導入する際は挙動(特にどのセマンティクスでビルドするか)を十分に理解してから使うのが安全です。

std::execution(senders/receivers)

std::execution(提案P2300)は、非同期処理と並行・並列処理を統一的に記述するための標準フレームワークです。<execution>ヘッダで提供されます。従来のstd::future/std::promiseの限界を越えて、非同期処理を「合成できる部品」として扱えるようにするのが狙いです。

中心となる抽象は3つです。

  • scheduler(スケジューラ): 実行資源への軽量なハンドルです。execution::scheduleを呼ぶと、そのスケジューラ上で完了するsenderが得られます。
  • sender(センダー): 非同期の仕事を記述し、完了時に「値」「エラー」「停止」のいずれかのシグナルを送ります。
  • receiver(レシーバー): 複数のチャンネルに対応したコールバックです。senderが送るシグナルを受け取ります。

これらとアルゴリズム群を組み合わせて、非同期処理のパイプラインを宣言的に書けます。P2300は2024年のSt. Louis会合(R10)で採択され、C++26に取り込まれました。NVIDIAのstdexecが参照実装として先行して公開されています。

並行処理の考え方そのものに興味があれば、他言語の安全設計を扱ったRust入門(rustupで始める)も合わせて読むと視野が広がります。

その他の注目機能

一次情報(cppreference / Wikipedia の提案番号付き記載)で確認できた、実務に効きそうな機能をいくつか挙げます。

  • #embed: バイナリなど外部リソースをソースへ直接埋め込むプリプロセッサ指令です(C23由来)。__has_embedも入ります。画像やシェーダをヘッダに変換する自前ツールが不要になります。
  • pack indexing(パックの添字アクセス): パラメータパックから特定要素を取り出す構文が入りました。従来のように再帰やヘルパで取り出す手間が減ります。
  • erroneous behaviour(提案P2795): 未初期化変数の読み取りを、これまでの未定義動作(UB)ではなく「erroneous behaviour(誤った動作)」として扱います。挙動は定義されるが正しくない、という中間的な位置づけで、コンパイラには診断が推奨されます。意図的に未初期化にしたい箇所は[[indeterminate]]属性で示せます。
  • bounds-hardened(境界強化)された標準ライブラリ: 標準ライブラリの範囲外アクセスに対する防御を強化する仕組みが入り、メモリ安全性の底上げに寄与します。

実務でいつ使えるか(コンパイラ実装状況)

ここが最も誤解を招きやすいところです。規格に入ったことと、手元のコンパイラで安定して使えることは別です。

執筆時点で、GCC・Clang・MSVCの各コンパイラはC++26機能の実装を進行中で、多くは実験的または一部のみという状況です。たとえば契約は一部のコンパイラで実験的に試せるという報告がありますが、対応バージョンやフラグ、対応範囲はコンパイラごとに差があります。リフレクションも実装が始まっていますが、まだ広く安定提供されている段階とは言えません。

WARNING

具体的な「どのコンパイラのどのバージョンで、どのフラグを付ければ何が動くか」は変化が速く、本記事では個別の対応状況を断定しません(要確認)。採用前に必ず各コンパイラのC++26ステータスページで最新情報を確認してください。

言語の年次アップデートという流れは他のエコシステムでも同じで、ES2026(ECMAScriptの新機能)のように「規格化」と「実装普及」のタイムラグを前提に付き合っていくのが現実的です。

まとめ

  • C++26は2026年3月に最終ドラフトが承認され、中身は事実上確定しました。ただしISOによる正式発行はこの後で、執筆時点では発行前と見るのが妥当です。
  • 3大機能は静的リフレクション(^^std::meta・スプライス[: :])、契約(pre/post/contract_assertと4つの評価セマンティクス)、std::execution(senders/receivers/schedulers)です。
  • #embed、pack indexing、erroneous behaviour、境界強化された標準ライブラリなど、堅実な改良も入りました。
  • コンパイラ実装は進行中で、多くが実験的・一部のみ。実務投入は各コンパイラの対応状況を確認してから判断しましょう。

新しい言語仕様を体系的に押さえたいときは、定番書での基礎固めが結局いちばんの近道です。学習用の書籍選びはプログラミング学習におすすめの本も参考にしてください。

参考リンク