我有一个编译时条件,使用
std::conditional<cond, TypeA, TypeB>
。就我而言,条件是析取,类似于 SimpleCondition<T>::value || ComplexCondition<T>::value
。在我的例子中,T 是一个长度为 n 的列表,我可以证明 SimpleCondition<T>::value
可以在 O(1) 时间内处理,而 ComplexCondition<T>::Value
需要 O(n) 时间。我想依靠快捷方式来确保我不会每次都计算 O(n) 边......假设我可以。
如果这些是运行时函数而不是编译时常量,则很容易表明
simpleCondition(t) || complexCondition(t)
将是快捷方式。编译时常量也能保证快捷方式吗?
作为更极端的情况,请考虑使用 SimpleCondition 来解决停止问题的情况。也许
ComplexCondition<T>::value
可以被证明对于许多值都终止,但是对于 SimpleCondition<T>::value
为真的情况,该证明不可用。在这种情况下,快捷方式的问题将是可证明编译的程序与不可编译的程序之间的区别。
在评估
SimpleCondition<T>::value || ComplexCondition<T>::value
时,编译器会查找并实例化 SimpleCondition<T>
和 ComplexCondition<T>
,然后查找 value
成员。实例化实际上是进行任何编译时评估的,因此虽然最终(假设它们都是true
)true || true
会“短路”,但此时不需要做任何额外的工作。
std::disjunction
。
std::disjunction_v<SimpleCondition<T>, ComplexCondition<T>>
给出的结果基本相同,但如果 ComplexCondition<T>
是 SimpleCondition<T>::value
,则不会实例化 true
。这意味着如果 ComplexCondition<T>
出现错误(例如无限递归),或者只需要大量编译时间资源来计算,它们就不会发生。
(对于
std::conjunction_v
案例,&&
)