CppCoreGuidelines T.25 避免互补的约束
06 September 2023
“Avoid complementary constraints”
理由
清晰。可读性好。通过互补约束表达的相反的要求很容易弄错。
例子
一开始,人们尝试通过互补要求来定义函数。
template<typename T> requires !C<T> // bad void f(); template<typename T> requires C<T> void f();
其实这样写会更好:
template<typename T> // general template void f(); template<typename T> // specialization by concept requires C<T> void f();
如果限制条件 C<T>
不满足要求,编译器会选择没有限制的那个模板。如果你不像或无法定义不受限制的版本的 f()
,你可以删除它。
template<typename T> void f() = delete;
编译器会选择重载的版本,或者抛出一个恰当的错误。
注意
互补限制条件在用到 enable_if
的代码里很常见。
template<typename T> enable_if<!C<T>, void> // bad f(); template<typename T> enable_if<C<T>, void> f();
注意
针对某个单一的要求,大家似乎认为互补要求是可以管理好的。其实,对于 2 个以上的需求,需要的定义数量指数级增长。
C1<T> && C2<T> !C1<T> && C2<T> C1<T> && !C2<T> !C1<T> && !C2<T>
这样,出错的概率也不断增长。
强化
- 标记函数中出现互补对的限制条件的情况
C<T>
与C<T>