根据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; }
在here,here甚至here中都找不到与此案例相关的参考。我已经随机尝试过类似的东西:
/* 1 */ template<AreEqComparable T1, T2>
/* 2 */ AreEqComparable<T1, T2>
/* 3 */ template<AreEqComparable<T1, T2>>
但是所有这些都引发语法错误。我认为答案应该在P0557的规范Bjarne Stroustrup中,但是对于我来说太长了。
答案 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
可以替换为特定的类型名称。
顺便说一句:
我上面提到的书简要介绍了概念。
在GCC中使用-fconcepts
启用概念。