概念要求中的析取

Disjunctions in a Concept requirement

A​​ requires expression 通常看起来像:requires ( parameter-list(optional) ) { requirement-seq }.

是否可以在不使用 requires constraint-expr 的情况下按要求在序列中形成析取 (||)。例如:

template<typename T> concept FooBarExpert = 
requires(T a, T b) { 
    {a.foo(b)} || {a.bar(b)}; // Req 1
    { a.baz() }; // Req 2
    // and onward
}; 

FooBarExpert 定义为适当 requires 表达式的合取(或析取)。

template<typename T> concept bool FooBarExpert =
( requires(T a, T b) {
    { a.foo(b) };
  } ||
  requires(T a, T b) {
    { a.bar(b) };
  }
) &&
requires(T a, T b) {
  { a.baz() };
};

通过 temp.constr.normal 中描述的称为 约束规范化 的过程, 原子约束 的联合和析取概念被分解。

仅:

  • 逻辑与&&,
  • 逻辑或||,
  • 括号表达式 ()
  • 形式为C<A1, A2, ..., An>的id表达式,其中C命名一个概念

分解。所有其他表达式都是原子约束

所以 require-expression 整体上是一个原子约束。在概念TS中,require-expression被分解了,但在C++20中没有。据我所知,我只是阅读了所有c++的论文与概念相关的委员会,原因是 require-expression 规范化可能会导致复杂性爆炸,从而影响编译速度。

所以:

requires(T a, T b) { 
    requires requires(T a, T b){a.foo(b)} 
          || requires(T a, T b){a.bar(b)}; // Req 1
    { a.baz() }; // Req 2
    // and onward
}; 

是一个原子约束。并且

  requires(T a, T b) { 
    {a.foo(b)} 
    { a.baz() }; // Req 2
     // and onward
    }
|| requires(T a, T b) { 
     {a.bar(b)} 
     { a.baz() }; // Req 2
      // and onward
     };

是两个原子约束的析取。 (两个requires-expression)

最后:

     ( requires(T a, T b) { a.foo(b); } || requires (T a, T b) { a.bar(b); } )
  && requires(T a, T b) { a.baz(); /* and onward */};

是析取与原子约束的结合。