概念要求中的析取

tan*_*ngy 5 c++ c++-concepts c++20

要求表达式通常如下所示: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
}; 
Run Code Online (Sandbox Code Playgroud)

Oli*_*liv 6

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

仅有的:

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

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

因此,需求表达式作为一个整体是一个原子约束。在概念 TS 中,要求表达式被分解,但在 C++20 中却没有分解。据我记得,我刚刚阅读了c++委员会所有与概念相关的论文,原因是要求表达式规范化可能会导致复杂性爆炸,从而影响编译速度。

所以:

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
}; 
Run Code Online (Sandbox Code Playgroud)

是一个原子约束。和

  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
     };
Run Code Online (Sandbox Code Playgroud)

是两个原子约束的析取。(两个需要表达

最后:

     ( 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 */};
Run Code Online (Sandbox Code Playgroud)

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