【C++17】構造化束縛の使い方 | pair, tuple, structを分解して受け取る方法

目次

はじめに

C++で、std::pairstd::tupleを返す関数を扱う際、従来はその戻り値を一度変数に受け取り、.firstget<0>を使って個々の要素にアクセスする必要があり、少し冗長でした。

C++17で導入された構造化束縛は、この問題をエレガントに解決します。auto [変数1, 変数2] = ... という特別な構文を使うことで、オブジェクトの各要素を、宣言と同時に個別の名前を持つ変数に直接「束縛(bind)」できます。


【前提】C++17とは?

C++17は、2017年に正式化されたC++言語の規格です。構造化束縛はこのC++17で導入されたため、利用するにはC++17に対応したコンパイラが必要です。


構造化束縛のサンプルコード

このコードは、pairstructarrayのそれぞれに対して、構造化束縛を使ってその要素を分解し、個別の変数として利用する例を示します。

完成コード

#include <iostream>
#include <string>
#include <tuple>   // pair (tupleヘッダにも含まれることが多い)
#include <array>

using namespace std;

// 1. 構造体(struct)
struct UserProfile {
    int id;
    string name;
};

int main() {
    cout << "--- pair ---" << endl;
    pair<int, string> p = {101, "佐藤"};
    // pairをidとnameに分解
    auto [id, name] = p;
    cout << "ID: " << id << ", 名前: " << name << endl;

    cout << "\n--- struct ---" << endl;
    UserProfile user = {202, "鈴木"};
    // 構造体をuser_idとuser_nameに分解
    auto [user_id, user_name] = user;
    cout << "ID: " << user_id << ", 名前: " << user_name << endl;
    
    cout << "\n--- 配列 ---" << endl;
    int point[] = {30, 40};
    // 配列をxとyに分解
    auto [x, y] = point;
    cout << "座標: (" << x << ", " << y << ")" << endl;
    
    return 0;
}

コードの解説

auto [id, name] = p;

これが構造化束縛の構文です。

  • auto: 型を自動推論するためのキーワードです。
  • [...]: 角括弧の中に、分解して受け取りたい変数名をカンマ区切りで列挙します。
  • = p: 右辺には、分解したいオブジェクトを置きます。

この一行は、内部的に以下のような処理を行っているのと似ています。 int id = p.first; string name = p.second; 構造化束縛を使うことで、これがより簡潔で直感的に記述できます。

分解できる対象

構造化束縛は、主に以下の3種類のオブジェクトに対して機能します。

  1. std::pair, std::tuple, std::array: これらのテンプレートクラス。
  2. structclass: 全ての非静的メンバ変数がpublicである場合に限る。
  3. C言語スタイルの配列

参照 (&) との組み合わせ

auto&auto&& を使うことで、元のオブジェクトのメンバへの参照として束縛することも可能です。これにより、分解した変数を通じて、元のオブジェクトの値を変更できます。

pair<int, string> user = {301, "高橋"};
auto& [ref_id, ref_name] = user;

ref_id = 302; // 参照を介して値を変更

cout << "変更後のuser.first: " << user.first << endl; // -> 302

まとめ

今回は、C++17の構造化束縛を使って、pairstructなどのオブジェクトを個別の変数に分解する方法を解説しました。

  • auto [v1, v2, ...] という構文で、オブジェクトのメンバを分解できる。
  • pair, tuple, struct, 配列など、様々なオブジェクトに対応している。
  • auto& を使えば、元のオブジェクトへの参照として束縛できる。

構造化束縛は、複数の値を返す関数や、mapのループ処理など、様々な場面でコードを劇的に簡潔にし、可読性を向上させる、現代C++の必須テクニックです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次