SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

【C++の新機能を理解する】最新バージョンを徹底解説!

C++の新機能を理解する──静的なoperator()/operator[]と多次元対応operator[]など言語仕様の強化

【C++の新機能を理解する】最新バージョンを徹底解説! 第2回

静的なoperator()/operator[]

 C++ 23では、関数オブジェクトやラムダ式の定義において、静的な(staticな)operator() および operator[] が利用可能になりました。

 C++ 23では、operator()/operator[]関数にstatic修飾子を付与して、オブジェクトの状態に関与しない演算子として定義できるようになりました。

基本的なoperator()とoperator[]

 まずは、これらの関数について簡単におさらいします。operator()は関数呼び出し演算子、operator[]は添え字演算子のオーバーロードです。これらの関数は、通常は暗黙のオブジェクトパラメータとしてthisを受け取り、自身と引数の演算結果を返します。

 以下のリストは、float型の配列に相当する構造体を定義し、演算子をオーバーロードして関数オブジェクトや添え字によるアクセスを可能にする例です。

リスト operator_overload.cpp
struct float_array {
  float data[10];	// 1次元配列

  float operator()(int index) {	// 関数オブジェクトの定義
    return this->data[index];	// thisでアクセスできる
  }

  float& operator[](int index) {	// 添え字演算子の定義
    return this->data[index];
  }
};
…略…
float_array arr = {1.0f, 2.0f, 3.0f, 4.0f};
cout << arr(0) + arr(1) + arr(2) + arr(3) << endl;	// 10、関数オブジェクト
arr[2] = 10.0f;	// 添え字で代入
cout << arr[2] << endl;	// 10

static operator()とoperator[]

 C++23で導入されたstatic修飾子を付けたoperator()とoperator[]を使うと、演算子がオブジェクトの状態を必要としない場合に、thisポインタの受け渡しに要するコストを省くことができます。

リスト static_operator.cpp
struct positive {
  static bool operator()(int x) {	// staticを付与
    return x > 0;	// thisは使えない
  }

  static bool operator[](int x) {
    return x > 0;
  }
};
…略…
positive p;
cout << p(10) << endl;	// 1
cout << p[-10] << endl;	// 0

 ラムダ式においてもstatic修飾子を付与できます。ラムダ式は、内部的には匿名構造体におけるoperator()関数のオーバーロードとして定義されるためです。

リスト static_operator.cpp
auto pf = [](int x) static -> bool { return x > 0; };
cout << pf(10) << endl;	// 1

多次元対応の添え字演算子operator[]

 C++ 23では、添え字演算子operator[]が多次元対応になり、多次元配列などを直感的に定義できるようになりました。

 これまで、ユーザー定義型で多次元配列などの挙動を実現するには、array[1][3] のように演算子を重ねるか、array(1, 3) のように関数呼び出し演算子で代用する必要がありました。C++23からは、array[1, 3] という自然な記述で要素にアクセスできます。

従来の多次元配列

 C++の標準的な配列は基本的に1次元であり、多次元配列を表現する場合は「配列の配列」として宣言します。

リスト sd_index_operator.cpp
float array[2][3] = {	// 2次元配列(3×2)を初期化
  {1.0f, 2.0f, 3.0f},
  {4.0f, 5.0f, 6.0f}
};
cout << array[1][2] << endl;	// 行、列の順に添え字を指定する

 この例では「2行×3列」の配列という構造になります。要素を指定するには、array[行のインデックス][列のインデックス]のように、二重添え字を用います。

 このとき、プログラマは「この配列が何行何列で、インデックスが行優先か列優先か」「どの引数が行でどの引数が列か」を常に意識してコーディングしないと、意図しない位置を参照したり、入れ替えを間違えたりといった不具合を起こしやすくなります。

 例えば行と列を逆に扱ってしまう、あるいはメモリ上の並び(つまり「行ごとに要素が並んでいる」)を考慮せずループを回すと、パフォーマンスや正しさに影響することもあります。

多次元対応のoperator[]

 C++23の多次元対応 operator[] を使うと、内部構造を隠蔽しつつ、自由度の高い多次元アクセスを実装できます。

リスト md_index_operator.cpp
struct array_2d {
  float data[3 * 2];	// (1)実データは6要素の1次元配列で構成

  float& operator[](int x, int y) {	// (2)多次元対応のoperator[]を定義
    return data[x + y * 3];
  }
};
…略…
array_2d array = {	// 配列を初期化
  1.0f, 2.0f, 3.0f,
  4.0f, 5.0f, 6.0f
};
cout << array[2, 1] << endl;	// (3)配列の添え字としてアクセスできる

 多次元対応の添え字演算子operator[]を使うとき、(1)のように実際の配列は多次元である必要はありません。(2)の添え字演算子のオーバーロードで、2つの引数を持つoperator[]関数を定義することで、(3)のように2つの添え字を指定できるようになります。

 この例では、1番目の引数を列(x)、2番目を行(y)とみなし、「列+行×3」(3は行当たりの列数)の演算によって適切な要素を返しています。

operator()による多次元対応

 多次元対応のoperator[]が使えるようになるまでは、関数呼び出し演算子operator()による代替手段(ブラケットではなく丸カッコ)がありました。

リスト md_index_operator.cpp
float& operator()(int x, int y) {
  return data[x + y * 3];
}
cout << array(2, 1) << endl;	// 10
array(2, 1) = 7.0f;
cout << array(2, 1) << endl;	// 7

 しかし、丸カッコによるアクセスは「それがコンテナの要素参照なのか、あるいは何らかの計算処理(関数呼び出し)なのか」がコードから判別しづらいという難点がありました。C++23で [] が多次元対応したことで、「これはコンテナの要素へのアクセスである」という意図を明確に示すことができるようになります。

次のページ
assume属性

この記事は参考になりましたか?

【C++の新機能を理解する】最新バージョンを徹底解説!連載記事一覧
この記事の著者

WINGSプロジェクト 山内 直(WINGSプロジェクト ヤマウチ ナオ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 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本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/23296 2026/02/16 08:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング