Namespaces
Variants

std:: common_reference

From cppreference.net
Metaprogramming library
Type traits
Type categories
(C++11)
(C++11) ( DR* )
Type properties
(C++11)
(C++11)
(C++14)
(C++11) (deprecated in C++26)
(C++11) ( until C++20* )
(C++11) (deprecated in C++20)
(C++11)
Type trait constants
Metafunctions
(C++17)
Supported operations
Relationships and property queries
Type modifications
Type transformations
(C++11) (deprecated in C++23)
(C++11) (deprecated in C++23)
(C++11)
(C++11) ( until C++20* ) (C++17)

common_reference
(C++20)
(C++11)
(C++17)
Compile-time rational arithmetic
Compile-time integer sequences
Определено в заголовочном файле <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 обозначает этот тип;
    • В противном случае, если 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& (т.е. оба являются типами 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() {}

Смотрите также

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