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 type`T0`

), the member`type`

names the same type as`T0`

. - If
`sizeof...(T)`

is two (i.e.,`T...`

contains two types`T1`

and`T2`

):- If
`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`

; - 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>`

is`U`

with the addition of`Ti`

's cv- and reference qualifiers, then the member type`type`

names that type; - 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 type`type`

names that type; - Otherwise, if
`std::common_type_t<T1, T2>`

is a valid type, then the member type`type`

names that type; - Otherwise, there is no member
`type`

.

- If
- If
`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:

- If
`T1`

is

and*cv1*X &`T2`

is

(i.e., both are lvalue reference types): their simple common reference type is*cv2*Y &`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; - If
`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`

. - Otherwise, one of the two types must be an lvalue reference type
`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`

. - Otherwise, there's no simple common reference type.

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