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

std::conjunction

Материал из cppreference.com
 
 
Библиотека метапрограммирования
Свойства типов
Категории типов
(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)

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

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

<tbody> </tbody>
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 доступна, если все Ts... имеют тот же тип, что и T
template<typename T, typename... Ts>
std::enable_if_t<std::conjunction_v<std::is_same<T, Ts>...>>
func(T, Ts...)
{
    std::cout << "все типы в пакете являются T\n";
}
 
// иначе
template<typename T, typename... Ts>
std::enable_if_t<!std::conjunction_v<std::is_same<T, Ts>...>>
func(T, Ts...)
{
    std::cout << "не все типы в пакете являются 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, "привет!");
}

Вывод:

все типы в пакете являются T
не все типы в пакете являются T

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

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