std::common_reference
Defined in header <type_traits>
|
||
|
template
<
class... T
>
struct common_reference; |
(since C++20) | |
Determines the common reference type of the types T..., that is, the type to which all the types in T... can be converted or bound. If such a type exists (as determined according to the rules below), the member type names that type. Otherwise, there is no member type. The behavior is undefined if any of the types in T... is an incomplete type other than (possibly cv-qualified) void
When given reference types, common_reference attempts to find a reference type to which the supplied reference types can all be bound, but may return a non-reference type if it cannot find such a reference type.
- If sizeof...(T) is zero, there is no member
type. - If sizeof...(T) is one (i.e.,
T...contains only one typeT0), the membertypenames the same type as T0 - If sizeof...(T) is two (i.e.,
T...contains two typesT1andT2):- Let type
Sbe the simple common reference type ofT1andT2(as defined below). The member typetypenamesSif all of the conditions below are satisfied:T1andT2are both reference typesSis well-formed
- Let type
|
(since C++23) |
-
- Otherwise, if
std::
basic_common_reference
<
std::remove_cvref_t
<T1>, std::remove_cvref_t
<T2>, T1Q, T2Q>
::
type
exists, where
TiQis a unary alias template such that TiQ<U> isUwith the addition ofTi's cv- and reference qualifiers, then the member typetype
- Otherwise, if
std::
basic_common_reference
<
std::remove_cvref_t
<T1>, std::remove_cvref_t
<T2>, T1Q, T2Q>
::
type
exists, where
-
- Otherwise, if
decltype(
false
? val<T1>
(
)
: val<T2>
(
)
)
, where
valis a function template template < class T> T val( ) ; , is a valid type, then the member typetype - Otherwise, if
std::common_type_t<T1, T2>
is a valid type, then the member type
type - Otherwise, there is no member
type.
- Otherwise, if
decltype(
false
? val<T1>
(
)
: val<T2>
(
)
)
, where
- If sizeof...(T) is greater than two (i.e.,
T...consists of the typesT1, T2, R...), then if std::common_reference_t<T1, T2> exists, the membertypedenotes std:: common_reference_t <std:: common_reference_t <T1, T2>, R...> if such a type exists. In all other cases, there is no membertype
The simple common reference type of two reference types T1 and T2 is defined as follows:
- If
T1iscv1 X&andT2iscv2 Y&(i.e., both are lvalue reference types): their simple common reference type is decltype( false ? std::declval <cv12 X& > ( ) : std::declval <cv12 Y& > ( ) ) , where cv12 is the union of cv1 and cv2 - If
T1andT2are both rvalue reference types: if the simple common reference type ofT1&andT2&(determined according to the previous bullet) exists, then letCdenote that type's corresponding rvalue reference type. If std::is_convertible_v<T1, C> and std::is_convertible_v<T2, C> are both true, then the simple common reference type ofT1andT2isC - Otherwise, one of the two types must be an lvalue reference type
A&and the other must be an rvalue reference typeB&&(AandBmight be cv-qualified). LetDdenote the simple common reference type of A& and B const&, if any. If D exists and std::is_convertible_v<B&&, D> is true, then the simple common reference type isD - Otherwise, there's no simple common reference type.
See Conditional operator for the definition of the type of expression false ? X : Y
Member types
| Name | Definition |
type
|
the common reference type for all T...
|
Helper types
|
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 { } ; |
||
The class template basic_common_reference is a customization point that allows users to influence the result of common_reference for user-defined types (typically proxy references). The primary template is empty.
Specializations
A program may specialize
std::basic_common_reference<T, U, TQual, UQual>
on the first two parameters T and U if
std::is_same_v
<T, std::decay_t
<T>>
and
std::is_same_v
<U, std::decay_t
<U>>
are both true
If such a specialization has a member named type, it must be a public and unambiguous member that names a type to which both TQual<T> and UQual<U> are convertible. Additionally,
std::
basic_common_reference
<T, U, TQual, UQual>
::
type
and
std::
basic_common_reference
<U, T, UQual, TQual>
::
type
A program may not specialize basic_common_reference on the third or fourth parameters, nor may it specialize common_reference
The standard library provides following specializations of basic_common_reference:
determines the common reference type of two pairs (class template specialization) |
|
determines the common reference type of a tuple and a tuple-like type (class template specialization) |
|
determines the common reference type of reference_wrapper and non-reference_wrapper (class template specialization) |
Notes
| Feature-test macro | Value | Std | Feature |
|---|---|---|---|
__cpp_lib_common_reference |
202302L |
(C++23) | Make std::common_reference_t of std::reference_wrapper a reference type |
Examples
#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() {}
See also
|
(C++11)
|
determines the common type of a group of types (class template) |
|
(C++20)
|
specifies that two types share a common reference type (concept) |