Skip to content

Latest commit

 

History

History
64 lines (45 loc) · 2.78 KB

relaxing_the_structured_bindings_customization_point_finding_rules.md

File metadata and controls

64 lines (45 loc) · 2.78 KB

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

  • cpp20[meta cpp]

このページは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
}
  • std::integral_constant[link /reference/type_traits/integral_constant.md]
  • tuple_size[link /reference/tuple/tuple_size.md]
  • tuple_element[link /reference/tuple/tuple_element.md]

出力

参照