前置依赖:
- _and
- _or
- _not
源码实现:
// 逻辑运算的外层包装
template<typename... _Bn>
struct conjunction
: __and_<_Bn...>
{ };
template<typename... _Bn>
struct disjunction
: __or_<_Bn...>
{ };
template<typename _Pp>
struct negation
: __not_<_Pp>
{ };
// 模板类别名, 提供便利接口
template<typename... _Bn>
inline constexpr bool conjunction_v = conjunction<_Bn...>::value;
template<typename... _Bn>
inline constexpr bool disjunction_v = disjunction<_Bn...>::value;
template<typename _Pp>
inline constexpr bool negation_v = negation<_Pp>::value;
- 简单的对外接口, 封装了 _and, _or, _not, 这也体现了命名规则, 下划线开始的名称, 变量名类名等都是对内接口, 如果暴露给用户的话要进行额外封装, 这里并没有体现出安全问题, 但可以给用户减少大量学习成本
- _v 后缀是为了提供便利的取值接口, 不然我们每次取值都会是类似于
conjunction<true_type>::value 这种情况, 对于它我们可以简写为 conjunction_v<true_type> 这里并没有简写多少, 可能以后会看到大量 ::type 的情况, 简写可能会很有用处
测试程序:
std::cout << "conjunction test: " << std::endl;
std::cout << "true && true = "
<< mySTL::conjunction_v<mySTL::true_type, mySTL::true_type> << std::endl;
std::cout << "true && true && false = "
<< mySTL::conjunction_v<mySTL::true_type, mySTL::true_type, mySTL::false_type> << std::endl;
std::cout << "disjunction test: " << std::endl;
std::cout << "false || false = "
<< mySTL::disjunction_v<mySTL::false_type, mySTL::false_type> << std::endl;
std::cout << "false || false || true = "
<< mySTL::disjunction_v<mySTL::false_type, mySTL::false_type, mySTL::true_type> << std::endl;
std::cout << "nagetion test: " << std::endl;
std::cout << "!true = "
<< mySTL::negation_v<mySTL::true_type> << std::endl;
std::cout << "!false = "
<< mySTL::negation_v<mySTL::false_type> << std::endl;