Namespaces
Variants

std:: common_reference

From cppreference.net
Metaprogramming library
Type traits
Type categories
(C++11)
(C++11) ( DR* )
Type properties
(C++11)
(C++11)
(C++14)
(C++11) (deprecated in C++26)
(C++11) ( until C++20* )
(C++11) (deprecated in C++20)
(C++11)
Type trait constants
Metafunctions
(C++17)
Supported operations
Relationships and property queries
Type modifications
Type transformations
(C++11) (deprecated in C++23)
(C++11) (deprecated in C++23)
(C++11)
(C++11) ( until C++20* ) (C++17)

common_reference
(C++20)
(C++11)
(C++17)
Compile-time rational arithmetic
Compile-time integer sequences
定义于头文件 <type_traits>
template < class ... T >
struct common_reference ;
(C++20 起)

确定类型 T... 的共同引用类型,即 T... 中所有类型均可转换或绑定到的类型。若存在此类类型(根据以下规则确定),则成员 type 将命名该类型。否则不存在成员 type 。若 T... 中的任何类型是(可能带有 cv 限定符的) void 以外的非完整类型,则行为未定义。

当给定引用类型时, common_reference 尝试找到一个能够绑定所有给定引用类型的引用类型,但若无法找到此类引用类型,则可能返回非引用类型。

  • sizeof... ( T ) 为零,则不存在成员 type
  • sizeof... ( T ) 为一(即 T... 仅包含一个类型 T0 ),则成员 type T0 同类型。
  • sizeof... ( T ) 为二(即 T... 包含两个类型 T1 T2 ):
    • 令类型 S T1 T2 简单公共引用类型 (定义如下)。当满足以下全部条件时,成员类型 type 将命名为 S
      • T1 T2 均为引用类型
      • 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 ) 大于二(即 T... 包含类型 T1, T2, R... ),则当 std :: common_reference_t < T1, T2 > 存在时,成员 type 表示 std :: common_reference_t < std :: common_reference_t < T1, T2 > , R... > (若该类型存在)。其余所有情况下均不存在成员 type

两个引用类型 T1 T2 简单公共引用类型 定义如下:

  • T1 cv1 X& T2 cv2 Y& (即两者均为左值引用类型):其简单公共引用类型为 decltype ( false ? std:: declval < cv12 X & > ( ) : std:: declval < cv12 Y & > ( ) ) ,其中 cv12 cv1 cv2 的限定符组合,若该类型存在且为引用类型;
  • T1 T2 均为右值引用类型:若 T1& T2& 的简单公共引用类型(根据前一条规则确定)存在,则令 C 表示该类型对应的右值引用类型。若 std:: is_convertible_v < T1, C > std:: is_convertible_v < T2, C > 均为 true ,则 T1 T2 的简单公共引用类型为 C
  • 否则,两个类型中一个必须是左值引用类型 A& ,另一个必须是右值引用类型 B&& A B 可能带有 cv 限定符)。令 D 表示 A & B const & 的简单公共引用类型(若存在)。若 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 结果。主模板为空。

特化

程序可以在前两个参数 T U 上特化 std :: basic_common_reference < T, U, TQual, UQual > ,当且仅当 std:: is_same_v < T, std:: decay_t < T >> std:: is_same_v < U, std:: decay_t < U >> 均为 true ,且其中至少一个参数依赖于程序定义类型。

如果存在这样的特化且其包含名为 type 的成员,则该成员必须是公开且无歧义的,并指定一个同时可接受 TQual < T > UQual < U > 转换的类型。此外, std :: basic_common_reference < T, U, TQual, UQual > :: type std :: basic_common_reference < U, T, UQual, TQual > :: type 必须表示同一类型。

程序不得对 basic_common_reference 的第三或第四个参数进行特化,也不得对 common_reference 本身进行特化。违反这些规则添加特化的程序将导致未定义行为。

标准库提供以下 basic_common_reference 的特化:

确定两个 pair 的公共引用类型
(类模板特化)
确定 tuple tuple-like 类型的公共引用类型
(类模板特化)
确定 reference_wrapper 与非 reference_wrapper 的公共引用类型
(类模板特化)

注释

功能测试 标准 功能
__cpp_lib_common_reference 202302L (C++23) 使 std::common_reference_t std::reference_wrapper 成为引用类型

示例

#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() {}

参见

确定一组类型的公共类型
(类模板)
指定两种类型共享一个公共引用类型
(概念)