Spec-Zone.ru › C++

std::conjunction

Определено в заголовке <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 >
inline 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 T\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 T\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 T
not all types in pack are T

См. также

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

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/types/conjunction

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API