前言析取,disjunction合取,conjunction否定,negation
前言C++17完善了< type_traits>,增加了3个有趣的traits。分别为析取traits,合取traits,否定traits,实现的方法有很多种,我使用VS2019的源码来写这篇博客。VS中标识符的命名风格非常统一。如果标识符的名字是下划线加上大写字母开头,那么代表这个标识符是内部使用,不会暴露给用户。首先,先做一下预备工作。介绍一下模板元编程的基本工具——integral_constant。
templatestruct integral_constant{ static constexpr T value = _Val; // ... };
上面是integral_constant的部分源码,虽然完整的源码不算太长,但是与我要讨论的无关,(而且我认为不太重要),可以看到该模板元函数仅仅是定义了一个关于类型T的编译期常量。
bool_constant:
在所有类型的常量中,我们常常会用到关于bool类型的常量,即integral_constant< bool, _Val >,所以我们就有了对bool常量的捷径。
templateusing bool_constant = integral_constant ; using true_type = bool_constant ; //has value true using false_type = bool_constant ; //has value false
bool_constant是一个bool常量,而对于bool常量,只有两种情况,这两种情况也很常见,我们也为其写了捷径,即true_type,相当于integral_constant 考虑普通的析取表达式,即一系列的条件表达式的逻辑或,像下面这样
而逻辑或拥有的特性便是:从左向右判断,如果有一个条件表达式为真,那么就直接截断,返回true。返回false的条件是所有的条件表达式都是false。而作为模板元函数的析取,操纵的“条件表达式”为一系列类型。disjunction获得一系列的类型,从左向右去萃取每种类型的value(这就必须保证每种类型都会返回一个常量value),如果发现value为true,那么直接返回true。否则,返回false。特殊考虑: 如果没有传入类型,C++规定,disjunction默认为false。
辅助traits: _Disjunction _Disjunction以下划线加上大写字母开头,表示用于内部实现,是一个辅助traits。主模板中,默认返回first的类型。在模板特化中,必须保证first::value为false,且传递过来至少两种类型。如果first::value为true,那么调用主模板;如果只传递过来一种类型,_Next就不存在,就会触发SFINAE,调用主模板。模板特化traits第一个类型的value为false,那么递归trait下一个。
如果_Traits为空,那么就返回false。如果_Traits参数包至少拥有一种类型,那么就继承_Disjunction的type。注意,是继承的type,而非使用using表达式。如果_Traits为空,那么主模板默认为false。在模板特化中,disjunction继承_Disjunction的type。而一旦某个traits为true,_Disjunction就会截断,直接返回type给disjunction,这也符合我们普通析取表达式的特性。
_v后缀: C++为返回value的模板元函数提供了调用的捷径。
合取与析取类似,即使用逻辑与连接一系列的条件表达式。
合取的特性为:如果是空,那么默认为true。从左向右匹配,如果某个value为false,那么直接截断,返回false。与disjunction完全类似,我们也有一个辅助traits。
辅助traits: _Conjunction 主模板默认为_First的类型。特化模板中,如果第一个类型的value为true,那么递归traits下一个。一旦有一个false,直接截断。
conjunction: 主模板默认为true。特化模板中,继承_Conjunction的type。类似的,conjunction也有shortcut。
否定极为简单,就是取反即可。 negative继承了bool_constant。bool_constant则定义了一个常量,为_Ty::value的否定。为了保证是bool类型的,所以使用了类型转换。//普通的析取表达式
condition1 || condition2 || conditon3 || ...
1 || 2 || 3 || 4;
int a = 0, b = 1, c= 2;
a < b || b < c || c < a;
// 该traits仅仅在VS2019内部使用,用于实现disjunction的辅助traits。
template
template
template
合取,conjunction
condition1 && condition2 && condition3 && ...
1 && 2 && 3 && 4;
int a = 0, b = 1, c = 2;
a < b && b < c && c < a;
template
template
template
否定,negation
template



