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):-
Пусть тип
Sбудет простым общим ссылочным типом дляT1иT2(как определено ниже). Член-типtypeобозначаетSпри выполнении всех следующих условий:-
T1иT2являются ссылочными типами -
Sявляется корректно сформированным
-
-
Пусть тип
|
(начиная с C++23) |
-
-
В противном случае, если существует
std
::
basic_common_reference
<
std::
remove_cvref_t
<
T1
>
,
std::
remove_cvref_t
<
T2
>
, T1Q, T2Q
>
::
type
, где
TiQявляется унарным псевдонимом-шаблоном таким, что TiQ < U > представляет собойUс добавлением cv- и ссылочных квалификаторовTi, тогда членtypeобозначает этот тип;
-
В противном случае, если существует
std
::
basic_common_reference
<
std::
remove_cvref_t
<
T1
>
,
std::
remove_cvref_t
<
T2
>
, T1Q, T2Q
>
::
type
, где
-
-
В противном случае, если
decltype
(
false
?
val
<
T1
>
(
)
:
val
<
T2
>
(
)
)
, где
valявляется шаблоном функции template < class T > T val ( ) ; , является допустимым типом, то членtypeобозначает этот тип; -
В противном случае, если
std::
common_type_t
<
T1, T2
>
является допустимым типом, то член
typeобозначает этот тип; -
В противном случае, член
typeотсутствует.
-
В противном случае, если
decltype
(
false
?
val
<
T1
>
(
)
:
val
<
T2
>
(
)
)
, где
-
Если
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&(т.е. оба являются типами lvalue-ссылок): их простой общий ссылочный тип — decltype ( false ? std:: declval < cv12 X & > ( ) : std:: declval < cv12 Y & > ( ) ) , где cv12 — объединение cv1 и cv2 , если такой тип существует и является ссылочным типом; -
Если
T1иT2оба являются типами rvalue-ссылок: если существует простой общий ссылочный тип дляT1&иT2&(определённый согласно предыдущему пункту), то пустьCобозначает соответствующий тип rvalue-ссылки. Если std:: is_convertible_v < T1, C > и std:: is_convertible_v < T2, C > оба равны true , то простой общий ссылочный тип дляT1иT2—C; -
В противном случае один из двух типов должен быть типом lvalue-ссылки
A&, а другой — типом rvalue-ссылки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 = 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
типа
(специализация шаблона класса) |
|
определяет общий ссылочный тип
reference_wrapper
и не-
reference_wrapper
(специализация шаблона класса) |
Примечания
| Макрос тестирования возможностей | Значение | Стандарт | Функция |
|---|---|---|---|
__cpp_lib_common_reference
|
202302L
|
(C++23) | Сделать std::common_reference_t для std::reference_wrapper ссылочным типом |
Примеры
#include <concepts> #include <type_traits> static_assert( std::same_as< int&, std::common_reference_t< std::add_lvalue_reference_t<int>, std::add_lvalue_reference_t<int>&, std::add_lvalue_reference_t<int>&&, std::add_lvalue_reference_t<int>const, std::add_lvalue_reference_t<int>const& > > ); int main() {}
Смотрите также
|
(C++11)
|
определяет общий тип для группы типов
(шаблон класса) |
|
(C++20)
|
указывает, что два типа имеют общий ссылочный тип
(концепт) |