最終更新日時(UTC):
が更新

履歴 編集

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

概要

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
}

出力

関連項目

参照