最終更新日時: 2025年07月10日 10時26分30秒 (JST)
Koichi Murase が更新

履歴 編集

# 構造化束縛がカスタマイゼーションポイントを見つけるルールを緩和 [P0961R1](C++20)

このページはC++20に採用された言語機能の変更を解説しています。

のちのC++規格でさらに変更される場合があるため関連項目を参照してください。

## 概要

C++17までは、構造化束縛する対象の型が`get()`メンバ関数を持っていればその関数でメンバ変数を抽出し、持っていなければ非メンバ関数の`get()`関数で抽出する仕様となっていた。

この仕様の問題として、非型テンプレートを持たない`get()`メンバ関数を持つ型を構造化束縛の対象とすると、不適格なプログラムになってしまっていた。例として、`std::shared_ptr`クラスは、生ポインタを取得するためのメンバ関数として`get()`を持つが、これは構造化束縛では使用できない。

この問題を解決するため、C++20では、構造化束縛する対象の型が「 非型テンプレートパラメータを持つ `get()`メンバ関数を持っていればその関数でメンバ変数を抽出し、持っていなければ非メンバ関数の`get()`関数で抽出する」という仕様に改訂となる。

これによって、`std::shared_ptr`のような非型テンプレートパラメータを持たない`get()`メンバ関数を持つ型に対して、カスタムの構造化束縛動作を、非メンバ関数の`get()`によって定義できるようになる。

## 例

    #include <memory>
    #include <tuple>
    #include <string>

    struct X : private std::shared_ptr<int> {
      std::string fun_payload;
    };

    template<int N> std::string& get(X& x) {
      if constexpr(N==0) return x.fun_payload;
    }

    namespace std {
      template<> struct tuple_size<X> : public std::integral_constant<int, 1> {};
      template<> struct tuple_element<0, X> {
        using type = std::string;
      };
    }

    int main()
    {
      X x;
      auto& [y] = x; // C++17では、get()メンバ関数が優先されるため、コンパイルエラーとなる
                     // C++20ではOK
    }

### 出力

## 関連項目

- C++17 構造化束縛

## 参照

- P0961R1 Relaxing the structured bindings customization point finding rules