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