Namespaces
Variants

std:: conjunction

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
conjunction
(C++17)
(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)

Compile-time rational arithmetic
Compile-time integer sequences
Определено в заголовочном файле <type_traits>
template < class ... B >
struct conjunction ;
(начиная с C++17)

Формирует логическую конъюнкцию типных свойств B... , фактически выполняя логическое И над последовательностью свойств.

Специализация std :: conjunction < B1, ..., BN > имеет открытый и однозначный базовый класс, который является

  • если sizeof... ( B ) == 0 , std:: true_type ; иначе
  • первый тип Bi в B1, ..., BN для которого bool ( Bi :: value ) == false , или BN если такого типа не существует.

Имена членов базового класса, за исключением conjunction и operator= , не скрыты и однозначно доступны в conjunction .

Конъюнкция является короткозамыкающей: если существует аргумент шаблонного типа Bi с bool ( Bi :: value ) == false , то инстанцирование conjunction < B1, ..., BN > :: value не требует инстанцирования Bj :: value для j > i .

Если программа добавляет специализации для std::conjunction или std::conjunction_v , поведение не определено.

Содержание

Параметры шаблона

B... - каждый шаблонный аргумент Bi для которого Bi :: value инстанцируется должен быть пригоден в качестве базового класса и определять член value конвертируемый в bool

Шаблон вспомогательной переменной

template < class ... B >
constexpr bool conjunction_v = conjunction < B... > :: value ;
(начиная с C++17)

Возможная реализация

template<class...>
struct conjunction : std::true_type {};
template<class B1>
struct conjunction<B1> : B1 {};
template<class B1, class... Bn>
struct conjunction<B1, Bn...>
    : std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {};

Примечания

Специализация conjunction не обязательно наследует ни от std:: true_type , ни от std:: false_type : она просто наследует от первого B , чьё значение ::value , явно преобразованное в bool , равно false , или от самого последнего B , когда все они преобразуются в true . Например, std :: conjunction < std:: integral_constant < int , 2 > , std:: integral_constant < int , 4 >> :: value равно 4 .

Сокращенное вычисление отличает conjunction от сверточных выражений : сверточное выражение, такое как ( ... && Bs :: value ) , инстанцирует каждый B в Bs , тогда как std :: conjunction_v < Bs... > останавливает инстанцирование, как только значение может быть определено. Это особенно полезно, если последующий тип дорого инстанцировать или он может вызвать критическую ошибку при инстанцировании с неправильным типом.

Макрос тестирования возможностей Значение Стандарт Функция
__cpp_lib_logical_traits 201510L (C++17) Трейты логических операторов типов

Пример

#include <iostream>
#include <type_traits>
// func is enabled if all Ts... have the same type as T
template<typename T, typename... Ts>
std::enable_if_t<std::conjunction_v<std::is_same<T, Ts>...>>
func(T, Ts...)
{
    std::cout << "All types in pack are the same.\n";
}
// otherwise
template<typename T, typename... Ts>
std::enable_if_t<!std::conjunction_v<std::is_same<T, Ts>...>>
func(T, Ts...)
{
    std::cout << "Not all types in pack are the same.\n";
}
template<typename T, typename... Ts>
constexpr bool all_types_are_same = std::conjunction_v<std::is_same<T, Ts>...>;
static_assert(all_types_are_same<int, int, int>);
static_assert(not all_types_are_same<int, int&, int>);
int main()
{
    func(1, 2, 3);
    func(1, 2, "hello!");
}

Вывод:

All types in pack are the same.
Not all types in pack are the same.

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

(C++17)
метафункция логического НЕ
(шаблон класса)
вариативная метафункция логического ИЛИ
(шаблон класса)