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...
|
Вспомогательные типы
<tbody> </tbody> 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) |
указывает, что два типа имеют общий ссылочный тип (концепт) |