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
Definido en el encabezado <type_traits>
template < class ... B >
struct conjunction ;
(desde C++17)

Forma la conjunción lógica de los rasgos de tipo B... , efectuando efectivamente una operación AND lógica sobre la secuencia de rasgos.

La especialización std :: conjunction < B1, ..., BN > tiene una base pública e inequívoca que es

  • si sizeof... ( B ) == 0 , std:: true_type ; de lo contrario
  • el primer tipo Bi en B1, ..., BN para el cual bool ( Bi :: value ) == false , o BN si no existe tal tipo.

Los nombres de los miembros de la clase base, excepto conjunction y operator= , no están ocultos y están disponibles de manera inequívoca en conjunction .

La conjunción es de cortocircuito: si hay un argumento de tipo plantilla Bi con bool ( Bi :: value ) == false , entonces instanciar conjunction < B1, ..., BN > :: value no requiere la instanciación de Bj :: value para j > i .

Si el programa añade especializaciones para std::conjunction o std::conjunction_v , el comportamiento es indefinido.

Contenidos

Parámetros de plantilla

B... - cada argumento de plantilla Bi para el cual Bi :: value es instanciado debe ser utilizable como clase base y definir el miembro value que sea convertible a bool

Plantilla de variable auxiliar

template < class ... B >
constexpr bool conjunction_v = conjunction < B... > :: value ;
(desde C++17)

Implementación posible

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> {};

Notas

Una especialización de conjunction no necesariamente hereda de std:: true_type o de std:: false_type : simplemente hereda del primer B cuyo ::value , convertido explícitamente a bool , es false , o del último B cuando todos se convierten a true . Por ejemplo, std :: conjunction < std:: integral_constant < int , 2 > , std:: integral_constant < int , 4 >> :: value es 4 .

La instanciación de cortocircuito diferencia a conjunction de las expresiones de plegado : una expresión de plegado, como ( ... && Bs :: value ) , instancia cada B en Bs , mientras que std :: conjunction_v < Bs... > detiene la instanciación una vez que el valor puede determinarse. Esto es particularmente útil si el tipo posterior es costoso de instanciar o puede causar un error grave cuando se instancia con el tipo incorrecto.

Macro de prueba de características Valor Estándar Característica
__cpp_lib_logical_traits 201510L (C++17) Rasgos de tipo de operador lógico

Ejemplo

#include <iostream>
#include <type_traits>
// func está habilitada si todos los Ts... tienen el mismo tipo que 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";
}
// en caso contrario
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!");
}

Salida:

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

Véase también

(C++17)
metafunción lógica NOT
(plantilla de clase)
metafunción lógica OR variádica
(plantilla de clase)