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.
sizeof...(T)
is zero, there is no member type
. sizeof...(T)
is one (i.e., T...
contains only one type T0
), the member type
names the same type as T0
. sizeof...(T)
is two (i.e., T...
contains two types T1
and T2
): T1
and T2
are both reference types, and the simple common reference type S
of T1
and T2
(as defined below) exists, then the member type type
names S
; 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>
is U
with the addition of Ti
's cv- and reference qualifiers, then the member type type
names that type; decltype(false? val<T1>() : val<T2>())
, where val
is a function template template<class T> T val();
, is a valid type, then the member type type
names that type; std::common_type_t<T1, T2>
is a valid type, then the member type type
names that type; type
. sizeof...(T)
is greater than two (i.e., T...
consists of the types T1, T2, R...
), then if std::common_reference_t<T1, T2>
exists, the member type
denotes std::common_reference_t<std::common_reference_t<T1, T2>, R...>
if such a type exists. In all other cases, there is no member type
. The simple common reference type of two reference types T1
and T2
is defined as follows:
T1
is cv1 X &
and T2
is cv2 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 that type exists and is a reference type; T1
and T2
are both rvalue reference types: if the simple common reference type of T1 &
and T2 &
(determined according to the previous bullet) exists, then let C
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 of T1
and T2
is C
; A &
and the other must be an rvalue reference type B &&
(A
and B
might be cv-qualified). Let D
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 is D
; See Conditional operator for the definition of the type of expression false ? X : Y
like the ones used above.
Name | Definition |
---|---|
type | the common reference type for all T... |
template< class... T > using common_reference_t = typename 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.
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
and at least one of them depends on a program-defined type.
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
must denote the same type.
A program may not specialize basic_common_reference
on the third or fourth parameters, nor may it specialize common_reference
itself. A program that adds specializations in violation of these rules has undefined behavior.
The standard library provides following specializations of basic_common_reference
:
(C++23) | determines the common reference type of two pair s (class template specialization) |
(C++23) | determines the common reference type of a tuple and a tuple-like type (class template specialization) |
(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) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/types/common_reference