C ++ 20:多种类型的概念及其约束,正确的语法?

Fal*_*nUA 20 c++ templates c++-concepts c++20

可以肯定的是c++20,根据即将到来的标准,根据最近的科隆ISO C ++会议的一份Reddit报告,我们将能够指定模板的概念,并且对于每个类/功能模板,我们将能够设置其类型的约束。 。但是,在文档和教程中(例如here),我找不到适用于多类型用例的正确语法。


假设我们有一个多类型的概念:

template<typename T1, typename T2>
concept AreEqComparable = requires(T1 a, T2 b) {
    { a == b } -> bool;
};
Run Code Online (Sandbox Code Playgroud)

假设我想在两个不同类型之间定义一个简单的比较函数。我怎样才能做到这一点?更具体地说,我应该在???下面的代码部分中写什么:

???
bool are_equal(T1 a, T2 b) { return a == b; }
Run Code Online (Sandbox Code Playgroud)

我在这里这里,甚至这里都没有找到关于这个案例的参考。我已经随机尝试过类似的东西:

/* 1 */ template<AreEqComparable T1, T2>
/* 2 */ AreEqComparable<T1, T2>
/* 3 */ template<AreEqComparable<T1, T2>>
Run Code Online (Sandbox Code Playgroud)

但是所有这些都引发语法错误。我认为答案应该在Bjarne Stroustrup的规范P0557中的某个位置,但是快速浏览后我找不到它。

L. *_* F. 14

您可以这样写:

template <typename T1, typename T2>
    requires AreEqComparable<T1, T2>
bool are_equal(T1 a, T2 b)
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

在这里,我们使用需求子句对类型模板参数施加要求。

  • @FalconUA我们可以编写`template &lt;typename T1,AreEqComparable &lt;T1&gt; T2&gt;`,但是有一点不同-它实际上是`AreEqComparable &lt;T2,T1&gt;`。我不太了解更紧凑的版本。 (2认同)
  • @ FalconUA,TS最初具有`AreEqComparable {T1,T2} bool are_equal(…);`,但是没有等效的速记形式使其成为C ++ 20。 (2认同)

Bar*_*rry 10

你可以写:

template <typename T1, AreEqComparable<T1> T2>
bool are_equal(T1, T2);
Run Code Online (Sandbox Code Playgroud)

这等效于:

template <typename T1, typename T2>
    requires AreEqComparable<T2, T1>
bool are_equal(T1, T2);
Run Code Online (Sandbox Code Playgroud)

此处的类型在约束中被翻转,AreEqComparable<T2, T1>而不是AreEqComparable<T1, T2>。对于许多概念,这当然很重要,但可能不会特别重要,因为==它本身在C ++ 20中变得对称(缺少病理情况,在实际代码中不应该存在)。而且,如果您确实要确定这种对称性是有效的,则可以始终在概念中将其明确化(就像EqualityComparableWith工作草案中那样):

template<typename T1, typename T2>
concept AreEqComparable = requires(T1 a, T2 b) {
    { a == b } -> bool;
    { b == a } -> bool;
};
Run Code Online (Sandbox Code Playgroud)

实际上,您可以通过翻转模板参数的顺序(h / t Matthieu M.)来以正确的顺序获得所需的约束:

template <typename T2, AreEqComparable<T2> T1>
bool are_equal(T1, T2);
Run Code Online (Sandbox Code Playgroud)

  • 那为什么不写`template &lt;typename T2, AreEqComparable&lt;T2&gt; T1&gt; bool are_equal(T1, T2)`呢?你会以正确的顺序得到参数...... (2认同)

Dav*_*ing 6

另一种完全避免引入模板参数的语法(以增加其他冗余为代价):

bool are_equal(auto x,auto y)
  requires AreEqComparable<decltype(x),decltype(y)>
  {return x==y;}
Run Code Online (Sandbox Code Playgroud)

  • @FalconUA:在“template&lt;…&gt;”之后或在“R f(…)”之后——当然,仅适用于后一种情况下的函数,它们甚至不需要是模板(例如,它们可以是类模板的成员) 。 (2认同)