名前空間
変種
操作

std::common_reference

From cppreference.com
< cpp‎ | types
 
 
メタプログラミングライブラリ
型特性
型のカテゴリ
(C++11)
(C++11)(DR*)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11) 
(C++11)
(C++11)
型のプロパティ
(C++11)
(C++11)
(C++14)
(C++11)(C++26で非推奨)
(C++11)(C++20まで*)
(C++11)(C++20で非推奨)
(C++11)
型特性定数
メタ関数
(C++17)
サポートされている操作
関係とプロパティクエリ
型の変更
(C++11)(C++11)(C++11)
型の変換
(C++11)(C++23で非推奨)
(C++11)(C++23で非推奨)
(C++11)
(C++11)(C++20まで*)(C++17)

common_reference
(C++20)
(C++11)
(C++17)
コンパイル時有理数演算
コンパイル時整数シーケンス
 
ヘッダ <type_traits> で定義
template< class... T >
struct common_reference;
(C++20以降)

T... の共通参照型を決定します。これは、T... 内のすべての型が変換またはバインドできる型です。そのような型が存在する場合(以下のルールに従って決定されます)、メンバー type がその型を指します。そうでない場合、メンバー type は存在しません。T... 内のいずれかの型が、(おそらくcv修飾された)void 以外の不完全型である場合、動作は未定義です。

参照型が与えられた場合、common_reference は提供された参照型すべてがバインドできる参照型を見つけようとしますが、そのような参照型が見つからない場合は非参照型を返すことがあります。

  • sizeof...(T) がゼロの場合、メンバー type は存在しません。
  • sizeof...(T) が1の場合(つまり、T... が1つの型 T0 のみを含む場合)、メンバー typeT0 と同じ型を指します。
  • sizeof...(T) が2の場合(つまり、T... が2つの型 T1T2 を含む場合)
    • ST1T2単純共通参照型とします(以下で定義)。以下の条件がすべて満たされる場合、メンバー型 typeS を指します。
      • T1T2 の両方が参照型である
      • S が整形式である
(C++23から)
  • そうでない場合、std::basic_common_reference<std::remove_cvref_t<T1>, std::remove_cvref_t<T2>, T1Q, T2Q>::type が存在する場合、ここで TiQ は単項エイリアステンプレートであり、TiQ<U>Ti の cv修飾子と参照修飾子を追加した U である場合、メンバー型 type はその型を指します。
    • そうでない場合、decltype(false? val<T1>() : val<T2>()) が有効な型である場合、ここで val は関数テンプレート template<class T> T val(); である場合、メンバー型 type はその型を指します。
    • そうでない場合、std::common_type_t<T1, T2> が有効な型である場合、メンバー型 type はその型を指します。
    • そうでない場合、メンバー type は存在しません。
  • sizeof...(T) が2より大きい場合(つまり、T... が型 T1, T2, R... で構成される場合)、std::common_reference_t<T1, T2> が存在する場合、メンバー type は、そのような型が存在すれば std::common_reference_t<std::common_reference_t<T1, T2>, R...> を表します。その他すべての場合、メンバー type は存在しません。

2つの参照型 T1T2単純共通参照型は次のように定義されます。

  • T1cv1 X& で、T2cv2 Y& である場合(つまり、両方が左辺値参照型である場合):それらの単純共通参照型は decltype(false? std::declval<cv12 X&>() : std::declval<cv12 Y&>()) です。ここで cv12cv1cv2 の結合であり、その型が存在し、かつ参照型である場合。
  • T1T2 の両方が右辺値参照型である場合:T1&T2& の単純共通参照型(前述の箇条書きに従って決定される)が存在する場合、その型の対応する右辺値参照型を C とします。std::is_convertible_v<T1, C> および std::is_convertible_v<T2, C> の両方が true である場合、T1T2 の単純共通参照型は C です。
  • そうでない場合、2つの型のうち1つが左辺値参照型 A& で、もう1つが右辺値参照型 B&& でなければなりません(AB は cv修飾されている可能性があります)。存在する場合、A&B const& の単純共通参照型を D とします。D が存在し、std::is_convertible_v<B&&, D>true である場合、単純共通参照型は D です。
  • そうでない場合、単純共通参照型は存在しません。

上記で使用されているような式 false ? X : Y の型の定義については、条件演算子を参照してください。

目次

[編集] メンバー型

名前 定義
type すべての T... の共通参照型

[編集] ヘルパー型

template< class... T >
using common_reference_t = std::common_reference<T...>::type;
template< class T, class U, template<class> class TQual, template<class> class UQual >
struct basic_common_reference {};

クラステンプレート basic_common_reference は、ユーザー定義型(通常はプロキシ参照)の common_reference の結果にユーザーが影響を与えることを可能にするカスタマイゼーションポイントです。プライマリテンプレートは空です。

[編集] 特殊化

プログラムは、std::is_same_v<T, std::decay_t<T>> および std::is_same_v<U, std::decay_t<U>> の両方が true であり、かつそれらの少なくとも1つがプログラム定義型に依存する場合、最初の2つのパラメータ TU に対して std::basic_common_reference<T, U, TQual, UQual> を特殊化できます。

このような特殊化が type という名前のメンバーを持つ場合、それは TQual<T>UQual<U> の両方が変換可能な型を指す、publicかつ曖昧さのないメンバーでなければなりません。さらに、std::basic_common_reference<T, U, TQual, UQual>::typestd::basic_common_reference<U, T, UQual, TQual>::type は同じ型を指す必要があります。

プログラムは、3番目または4番目のパラメーターに対して basic_common_reference を特殊化することはできませんし、common_reference 自体を特殊化することもできません。これらのルールに違反して特殊化を追加するプログラムの動作は未定義です。

標準ライブラリは、basic_common_reference の以下の特殊化を提供します。

2つのpairの共通参照型を決定する
(クラステンプレート特殊化) [編集]
tupletuple-like 型の共通参照型を決定する
(クラステンプレート特殊化) [編集]
reference_wrapper と非 reference_wrapper の共通参照型を決定します。
(クラステンプレート特殊化) [編集]

[編集] 注釈

機能テストマクロ 規格 機能
__cpp_lib_common_reference 202302L (C++23) std::reference_wrapperstd::common_reference_t を参照型にする

[編集]

#include <concepts>
#include <type_traits>
 
static_assert(
    std::same_as<
        int&,
        std::common_reference_t<
            std::add_lvalue_reference_t<int>,
            std::add_lvalue_reference_t<int>&,
            std::add_lvalue_reference_t<int>&&,
            std::add_lvalue_reference_t<int>const,
            std::add_lvalue_reference_t<int>const&
        >
    >
);
 
int main() {}

[編集] 関連項目

型のグループの共通の型を決定する
(クラステンプレート) [編集]
2つの型が共通の参照型を共有することを規定する
(コンセプト) [編集]
English 日本語 中文(简体) 中文(繁體)