ダウンロード サンプルファイル (2.1 KB)
C++は、C言語より派生した歴史のあるオブジェクト指向言語です。このC++は、システムプログラミングにも適した高速で緻密なコーディングのための言語ですが、絶え間なく進化を続けており、モダンな言語仕様やライブラリ機能も貪欲に取り込んでいます。本連載では、このC++の最新バージョンにフォーカスし、その新機能を紹介していきます。また、最新バージョン以前の機能にも関連の深いものについて言及することで、新機能をつながりとして理解できることも意識します。第5回では、前回に引き続きC++ 23における標準ライブラリの機能強化について、println関数などの出力関連、mdspanなどの部分シーケンス関連、flat_set/flat_mapなどのコレクション関連を中心に紹介します。
対象読者
- C++の最新バージョンの機能を把握したい方
- C++の経験者で、C++に改めて入門したい方
- プログラミング言語の最新パラダイムに関心のある方
必要な環境
本記事のサンプルコードは、以下の環境で動作を確認しています。なお、一部のサンプルは以下の環境では動作しないか、あるいは実験的実装(Experimental)なので動作が不安定になる可能性があります。
-
macOS Sequoia / Windows 11
- Xcode Command Line Tools 16.0(Clang 16.0.0)
- w64devkit 2.4.0(GCC 15.2.0)
主要コンパイラのC++対応状況およびC++プログラムのコンパイルについての説明は、第1回を参照してください。
出力関連の強化
C++ 23では、フォーマット付き出力のためのstd::print/std::println関数が使えるようになりました。
C++では、標準出力などに情報を書き出したい場合、高水準のストリーム出力であるcoutの利用が基本です(本連載もそれに倣っています)。しかしながら、書き出す値が増えたり、書式指定が必要な場合には、たくさんの「<<」演算子やマニュピレータ(出力形式を指定するオブジェクト)が必要になるなど、コードが長くなり可読性も下がる傾向があります。このため、できれば従来のprintf関数のようにシンプルに書式指定したいというニーズがありました。
簡潔でフォーマット可能な出力のためのstd::print/std::println[C++ 23]
C++ 23では、printf関数のような書式指定文字列を使った出力を行う、print/println関数が利用できるようになりました。両者の違いは、最後に改行文字を出力するかどうかです。これらの関数には、第1引数にストリームを受け取るものと、従来のファイルハンドルを受け取るオーバーロードがあります。
前者を使う場合には<iostream>を、後者を使う場合には<print>を、それぞれincludeします。書式指定文字列自体は共通なので、以降は<iostream>を使っていきます。
以下のリストは、"Hello, world!"+改行を得る出力を、それぞれの関数で記述したものです。
#include <iostream> #include <print> …略… print(cout, "Hello, world!\n"); println(cout, "Hello, world!"); print(stdout, "Hello, world!\n"); println(stdout, "Hello, world!");
std::formatによる書式指定[C++ 20]
print/println関数における書式指定自体は、C++ 20で利用できるようになったstd::format関数に準拠したものを使います。基本となるのは、値を埋め込む置換フィールド(プレースホルダー)です。
以下のように、中カッコ({ })を使って置換フィールドを指定します。中カッコに引数ID(位置パラメータ)を埋め込み、引数の位置を0からの数値で指定することもできます。このように、printf関数における%d、%sといったものではなく、多くのモダンなプログラミング言語で採用されているプレースフォルダを使うのが特徴です。
以下のリストは、置換フィールドの基本的な使用例です。位置パラメータのありとなしの例となっています。
auto x = 2, y = 3, z = 5;
println(cout, "{} + {} = {}", x, y, z); // 順番に入る
println(cout, "{2} + {1} = {0}", z, y, x); // 2番目、1番目、0番目の順に入る
置換フィールドにオプションを埋め込むことで、値の出力形式を細かく指定可能です。オプションは、従来のprintf関数におけるものを踏襲していますが、省略して既定のフォーマットで出力させることができます。
オプションは、位置パラメータと区別するために、コロン(:)で区切って指定します。オプションには、型、幅、フィル(埋め文字)、揃え方向(アラインメント)、符号、プレフィクス、精度などを以下の形式で指定できます。
[[フィル]アラインメント][符号][#][0][幅][.精度]L型
- フィル:揃えるときに使う埋め文字(既定値は半角スペース)
- アラインメント:揃え方向の指定(>:右揃え、<:左揃え、^:中央揃え)
- 符号:符号の指定(+:正数に符号を表示する、-:負数のみ符号を表示(既定)、スペース:正数にはスペースを表示)
- #:代替表現(0xなど形式がわかる表記)の指定
- 0:符号を考慮して0で埋める指定
- 幅:出力する幅(置換フィールドを使って変数で指定可)
- 精度:浮動小数点数では小数点以下の桁数、文字列では文字数(置換フィールドを使って変数で指定可)
- L:ロケールを考慮するか
- 型:値の表現方法
型には、以下の表に挙げるものをデータ型に応じて指定できます(?は、C++ 23から利用可能になったデバッグ出力の指定です)。
| 型 | 型指定 | 概要 |
| 文字列 | s(既定)または? | 文字列をそのまま、あるいは引用符で囲ってエスケープ処理を施して出力 |
| 文字 | c(既定)または? | 文字をそのまま、あるいは引用符で囲ってエスケープ処理を施して出力 |
| 論理値 | s(既定) | false/trueのいずれかで出力 |
| 整数 | b/B, d, o, x/X, c | 2進整数、10進整数、8進整数、16進整数、文字 |
| 浮動小数点数 | f/F, e/E, a/A, g/G(既定) | 指数表記なし、指数表記あり、16進数で指数表記、値によって指数表記 |
| ポインタ | p | アドレスを出力 |
以下は、主なオプションの使用例です。
auto s = "Hello\nWorld!";
auto c = '\t';
auto d = 12345678;
auto f = 3.14159;
void* p = &x;
println(cout, "String: {:s}", s); // String: Hello
// World!
println(cout, "String(debug): {:?}", s); // "Hello\nWorld!"
println(cout, "Character: {:c}", c); // (見えないがタブが出力)
println(cout, "Character(debug): {:?}", c); // '\t'
println(cout, "Integer: {:#032b}, {:010d}, {:020o}, {:#020x}", d, d, d, d);
// 0b000000101111000110000101001110, 0012345678, 00000000000057060516, 0x000000000000bc614e
println(cout, "Float: {:.2f}, {:e}, {:a}, {:g}", f, f, f, f);
// 3.14, 3.141590e+00, 1.921f9f01b866ep+1, 3.14159
println(cout, "Pointer: {:p}", p); // 0x7ff7b4220c74
この記事は参考になりましたか?
- 【C++の新機能を理解する】最新バージョンを徹底解説!連載記事一覧
-
- C++の新機能を理解する――出力と部分シーケンス関連の機能強化
- C++の新機能を理解する――列挙型と状態チェック関連の機能強化
- C++の新機能を理解する──rangesライブラリとジェネレータ
- この記事の著者
-
WINGSプロジェクト 山内 直(WINGSプロジェクト ヤマウチ ナオ)
<WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook <個人紹介>WINGSプロジェクト所属のテクニカルライター。出版社を経てフリーランスとして独立。ライター、エディター、デベロッパー、講師業に従事。屋号は「たまデジ。」。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
