std::conjunction是否应支持可显式转换为bool类型的输入?
结论:不支持,核心原因来自标准条款的内在矛盾以及类型特性的隐含约束:
标准条款的矛盾点
C++20的[meta.logical]条款明确说明,std::conjunction、std::disjunction会将输入类型的value成员显式转换为bool来判断真假——比如conjunction<B1,…,BN>会以列表中首个bool(Bi::value)为false的Bi作为基类。
但同一章节的[meta.logical]/5.1等条款同时要求:conjunction的结果类型的value成员,必须与首个“假值”输入的value成员完全一致。这就和conjunction_v的定义产生了冲突:
template<class... B> inline constexpr bool conjunction_v = conjunction<B...>::value;
conjunction_v要求conjunction<B...>::value能隐式转换为bool,但如果输入类型的value仅支持显式转换为bool(比如自定义的MyBool类型),这里会直接触发编译错误——因为显式转换不能被隐式调用。
关于[meta.rqmts]的隐含约束
虽然[meta.rqmts]条款没有准确定义“类型特性”,也没有明确要求conjunction必须接收“类型特性”作为输入,但它暗示所有标准类型特性都是integral_constant的特化。而integral_constant的模板参数要求是整数类型(标准定义:template<class T, T v> struct integral_constant;,其中T为整数类型),其value成员本身就是整数类型,天然支持隐式转换为bool。
这意味着标准中逻辑元函数的设计初衷,是针对符合integral_constant特化的类型特性,而非自定义的仅显式转bool的类型。
总结
即便[meta.logical]提到了显式转换为bool的判断逻辑,但结合结果类型value必须与输入一致的要求,以及conjunction_v等变量模板的强制隐式转换需求,C++20的std::conjunction、std::disjunction、std::negation实际上并不支持仅能显式转换为bool的自定义输入类型。
内容的提问来源于stack exchange,提问作者jacobsa

