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

履歴 編集

class template
<type_traits>

std::basic_common_reference(C++20)

namespace std {
  template<class T, class U, template<class> class TQual, template<class> class UQual>
  struct basic_common_reference {};
}

概要

任意の2つのプログラム定義型について、common_referenceで共通の参照型を取得できるようにアダプトする。

特殊化

basic_common_referenceは以下の条件を満たす場合に、型T, Uを対象に取るものに限ってユーザー定義の特殊化が許可されている(TQual, UQualに対しては特殊化してはならない)。

  • T, Uの少なくとも片方はプログラム定義型に依存している
    • プログラム定義型とは、標準ライブラリの型を除いた、ユーザーによって定義された型のこと
    • 「プログラム定義型に依存している」とは例えば、プログラム定義型に対するvector等の特殊化のこと
  • T, Uに対するdecayの適用はともに恒等写像となる
    • T, Uはともに配列型ではなく
    • T, Uはともに関数型でもなく
    • T, Uはともに参照型でもなく
    • T, UはともにCV修飾もされていない

そして、そのような特殊化は必ずしもメンバ型typeを持たなくても構わない。もしtypeを定義する場合はpublicにただ一つだけ定義し、その型はTQual<T>, UQual<U>から明示的に変換可能な型である必要がある。
なお、TQual<T>, UQual<U>はそれぞれ、使用時にcommon_referenceに渡された実引数型の参照・CV修飾を対応するT, Uにそのままコピーしたような型を示すエイリアステンプレートである。

そして、その特殊化はT, Uの引数順を入れ替えても同じ結果を返す(対称性を持つ)必要がある。

上記のいずれかの規則に違反した特殊化を定義したとしてもコンパイルエラーにはならず、未定義動作となる。

なお、common_type, basic_common_reference以外の<type_traits>内テンプレートに対するユーザー定義の特殊化は許可されていない。

#include <iostream>
#include <type_traits>
#include <concepts>

//共通の参照型を作るための基底型
struct B {};

//std::common_referenceにアダプトしたい2つの型
struct T : B {};
struct U : B {};

//std::common_referenceおよびstd::common_reference_withにアダプトする
namespace std {
  template<template<class> class TQual, template<class> class UQual>
  struct basic_common_reference<T, U, TQual, UQual> {
    using type = B&;
  };

  //対称性のために引数順を逆にしたものも定義する
  template<template<class> class TQual, template<class> class UQual>
  struct basic_common_reference<U, T, TQual, UQual> {
    using type = B&;
  };
}


int main()
{
  static_assert(std::same_as<std::common_reference_t<T, U>, B&>);
  static_assert(std::same_as<std::common_reference_t<U, T>, B&>);
}

出力

バージョン

言語

  • C++20

処理系

関連項目

参照