Пространства имён
Варианты
Действия

std::common_reference

Материал из cppreference.com
< cpp‎ | types
 
 
Библиотека метапрограммирования
Свойства типов
Категории типов
(C++11)
(C++14)  
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
Свойства типов
(C++11)
(C++11)
(C++14)
(C++11)
(C++11)(до C++20*)
(C++11)(устарело в C++20)
(C++11)
Константы свойств типа
Метафункции
(C++17)
Поддерживаемые операции
Запросы отношений и свойств
Модификации типов
(C++11)(C++11)(C++11)
Преобразования типов
(C++11)(устарело в C++23)
(C++11)(устарело в C++23)
(C++11)
(C++11)
(C++17)

common_reference
(C++20)
(C++11)(до C++20*)(C++17)
Рациональная арифметика времени компиляции
Целочисленные последовательности времени компиляции
 
Определено в заголовочном файле <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 типов
(специализация шаблона класса) [править]

[править] Примечание

[править] Пример

[править] Смотрите также

определяет общий тип группы типов
(шаблон класса) [править]
указывает, что два типа имеют общий ссылочный тип
(концепт) [править]