std::common_reference
Определено в заголовочном файле <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
):- Если
T1
иT2
являются ссылочными типами, а простой общий ссылочный типS
типовT1
иT2
(как определено ниже) существует, то тип элементtype
именуетS
; - Иначе, если существует std::basic_common_reference<std::remove_cvref_t<T1>, std::remove_cvref_t<T2>, T1Q, T2Q>::type, где
TiQ
это унарный псевдоним шаблона, такой что TiQ<U> равенU
с добавлениемTi
-ых cv- и ссылочных квалификаторов, тогда тип элемент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 = typename 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
для определяемых пользователем типов (обычно это прокси-ссылки). Основной шаблон пуст.
[править] Специализации
Программа может специализировать std::basic_common_reference<T, U, TQual, UQual> по первым двум параметрам T
и U
, если 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 типов (специализация шаблона класса) |
[править] Примечание
Этот раздел не завершён |
[править] Пример
Этот раздел не завершён Причина: нет примера |
[править] Смотрите также
(C++11) |
определяет общий тип группы типов (шаблон класса) |
(C++20) |
указывает, что два типа имеют общий ссылочный тип (концепт) |