| Type traits | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Compile-time rational arithmetic | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Compile-time integer sequences | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
(C++14) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Defined in header <type_traits> | ||
template<class...B> struct conjunction; | (since C++17) | |
Forms thelogical conjunction of the type traitsB..., effectively performing a logical AND on the sequence of traits.
The specializationstd::conjunction<B1, ..., BN> has a public and unambiguous base that is
Bi inB1, ..., BN for whichbool(Bi::value)==false, orBN if there is no such type.The member names of the base class, other thanconjunction andoperator=, are not hidden and are unambiguously available inconjunction.
Conjunction is short-circuiting: if there is a template type argumentBi withbool(Bi::value)==false, then instantiatingconjunction<B1, ..., BN>::value does not require the instantiation ofBj::value forj > i.
If the program adds specializations forstd::conjunction orstd::conjunction_v, the behavior is undefined.
Contents |
| B... | - | every template argumentBi for whichBi::value is instantiated must be usable as a base class and define membervalue that is convertible tobool |
template<class...B> constexprbool conjunction_v= conjunction<B...>::value; | (since 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>{}; |
A specialization ofconjunction does not necessarily inherit from eitherstd::true_type orstd::false_type: it simply inherits from the firstB whose::value, explicitly converted tobool, isfalse, or from the very lastB when all of them convert totrue. For example,std::conjunction<std::integral_constant<int,2>,std::integral_constant<int,4>>::value is4.
The short-circuit instantiation differentiatesconjunction fromfold expressions: a fold expression, like(...&& Bs::value), instantiates everyB inBs, whilestd::conjunction_v<Bs...> stops instantiation once the value can be determined. This is particularly useful if the later type is expensive to instantiate or can cause a hard error when instantiated with the wrong type.
| Feature-test macro | Value | Std | Feature |
|---|---|---|---|
__cpp_lib_logical_traits | 201510L | (C++17) | Logical operator type traits |
#include <iostream>#include <type_traits> // func is enabled if all Ts... have the same type as Ttemplate<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";} // otherwisetemplate<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>constexprbool 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!");}
Output:
All types in pack are the same.Not all types in pack are the same.
(C++17) | logical NOT metafunction (class template)[edit] |
(C++17) | variadic logical OR metafunction (class template)[edit] |