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

时间:2019-07-11 00:21:35

标签: c++ templates c++20 c++-concepts

根据this reddit report,似乎在即将到来的c++20标准中,我们将能够指定模板的concept,对于每个类/函数模板,我们将能够在其类型上设置constraints。但是,在文档和教程(例如here)中,我找不到适用于多类型用例的正确语法。


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

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

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

???
bool are_equal(T1 a, T2 b) { return a == b; }

herehere甚至here中都找不到与此案例相关的参考。我已经随机尝试过类似的东西:

/* 1 */ template<AreEqComparable T1, T2>
/* 2 */ AreEqComparable<T1, T2>
/* 3 */ template<AreEqComparable<T1, T2>>

但是所有这些都引发语法错误。我认为答案应该在P0557的规范Bjarne Stroustrup中,但是对于我来说太长了。

4 个答案:

答案 0 :(得分:11)

您可以这样写:

template <typename T1, typename T2>
    requires AreEqComparable<T1, T2>
bool are_equal(T1 a, T2 b)
{
    // ...
}

在这里,我们使用 requires-clause 对类型模板参数施加要求。

答案 1 :(得分:8)

您可以写:

template <typename T1, AreEqComparable<T1> T2>
bool are_equal(T1, T2);

这等效于:

template <typename T1, typename T2>
    requires AreEqComparable<T2, T1>
bool are_equal(T1, T2);

这里的类型在约束中翻转,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;
};

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

template <typename T2, AreEqComparable<T2> T1>
bool are_equal(T1, T2);

答案 2 :(得分:3)

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

bool are_equal(auto x,auto y)
  requires AreEqComparable<decltype(x),decltype(y)>
  {return x==y;}

答案 3 :(得分:2)

在GCC 8.2.0中,概念应这样写:

concept bool ConceptName = /* ... */

但是C++ Templates: The Complete Guide没有提到bool。由于C ++ 20标准尚未发布,因此很难说是正确的。

对于需要一个参数(不一定是类型)的概念,有一个简写:

template <UnaryConceptName T>

对于需要两个或多个参数的用户,没有速记:

template <typename T1, typename T2> requires BinaryConceptName<T1, T2>

typename可以替换为特定的类型名称。

顺便说一句:

  1. 我上面提到的书简要介绍了概念。

  2. 在GCC中使用-fconcepts启用概念。