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 membertype
names the same type as T0 - If sizeof...(T) is two (i.e.,
T...
contains two typesT1
andT2
):- Let type
S
be the simple common reference type ofT1
andT2
(as defined below). The member typetype
namesS
if all of the conditions below are satisfied:T1
andT2
are both reference typesS
is 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
TiQ
is a unary alias template such that TiQ<U> isU
with 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
val
is 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 membertype
denotes 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
T1
iscv1 X&
andT2
iscv2 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
T1
andT2
are both rvalue reference types: if the simple common reference type ofT1&
andT2&
(determined according to the previous bullet) exists, then letC
denote 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 ofT1
andT2
isC
- Otherwise, one of the two types must be an lvalue reference type
A&
and the other must be an rvalue reference typeB&&
(A
andB
might be cv-qualified). LetD
denote 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 pair s (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) |