C++の基礎 - 構造化束縛

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
2024年9月19日 (木) 11:43時点におけるWiki (トーク | 投稿記録)による版 (ページの作成:「== 概要 == 構造化束縛は、C++17で導入された機能であり、複数の変数を同時に初期化することができる便利な構文である。<br> 構造化束縛は、コードの可読性を向上させて、複数の値を扱う場合のボイラープレートコード (冗長さ) が軽減される。<br> <br> 基本的な使用方法としては、配列、タプル、構造体等から複数の値を1度で取得して、個別の変数に…」)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
ナビゲーションに移動 検索に移動

概要

構造化束縛は、C++17で導入された機能であり、複数の変数を同時に初期化することができる便利な構文である。
構造化束縛は、コードの可読性を向上させて、複数の値を扱う場合のボイラープレートコード (冗長さ) が軽減される。

基本的な使用方法としては、配列、タプル、構造体等から複数の値を1度で取得して、個別の変数に割り当てることができる。 例えば、関数が複数の値を返す場合において、以前は各値を個別に取得する必要があったが、構造化束縛を使用することにより1行で簡潔に記述できる。

この機能は配列に対しても適用可能である。
特に、固定長の配列から値を取得する場合に便利であり、各要素を個別の変数として扱うことができる。

また、publicメンバを持つ構造体に対して構造化束縛を適用することにより、メンバ変数を直接個別の変数として扱うこともできる。
これにより、構造体のメンバにアクセスする場合の記述が簡略化される。

さらに、参照による束縛も可能であり、値のコピーではなく元のデータへの参照を保持できる。
この特性は、大きなオブジェクトを扱う場合やパフォーマンスが重要な場面で特に有効である。

const修飾子との組み合わせも重要な特徴である。
構造化束縛で取得した変数を変更不可能にすることができるため、意図しない変更を防ぐのに役立つ。

ラムダ式との組み合わせも強力である。
例えば、std::pairクラスの要素を持つコンテナをイテレートする場合に、各要素のペアを直接分解して扱うことができる。
これにより、コードがより直感的で可読性が上がる。

構造化束縛は、複数の戻り値を持つ関数、タプルや構造体の要素への簡易アクセス、イテレーションの簡素化等、様々な場面で活用できる。
この機能を適切に使用することにより、C++のコードをより簡潔かつ表現力豊かにすることができる。

ただし、過度に複雑な構造に対して使用するとコードの理解が難しくなる可能性もあるため、適切な使用が求められる。

特に、関数から複数の値を返す場合やコンテナの要素をイテレートする場合に便利である。


構造化束縛の基本

配列、タプル、構造体等から複数の値を1度に取得して、個別の変数に割り当てることができる。

 std::tuple<int, std::string, double> getData()
 {
    return {1, "Hello", 3.14};
 }
 
 // 使用例
 auto [id, name, value] = getData();



配列との使用

固定長の配列に対して使用することができる。

 int arr[]      = {1, 2, 3};
 auto [a, b, c] = arr;



構造体との使用

publicメンバを持つ構造体に対して適用することができる。

 struct Point {
    int x;
    int y;
 };
 
 // 使用例
 Point p{10, 20};
 auto [x, y] = p;



参照による束縛

値のコピーではなく、参照として変数を束縛することもできる。

 auto& [ref_x, ref_y] = p;
 ref_x                = 100;  // pのxも変更される



constとの組み合わせ

const修飾子を使用して、変更不可能な変数として束縛することもできる。

 const auto [const_x, const_y] = p;
 // const_x                    = 100;  // エラー: constなので変更不可



ラムダ式での使用

ラムダ式の引数としても構造化束縛を使用することができる。

 std::vector<std::pair<int, std::string>> vec = {{1, "one"}, {2, "two"}};
 std::for_each(vec.begin(), vec.end(), [](const auto& [num, str]) {
    std::cout << num << ": " << str << std::endl;
 });