the online C++ draft和cppreference都定义了标准Relation
概念,如下所示:
template <class R, class T, class U>
concept Relation =
std::Predicate<R, T, T> && std::Predicate<R, U, U> &&
std::Predicate<R, T, U> && std::Predicate<R, U, T>;
这个定义使我感到惊讶,因为我希望看到类似的东西
template <class R, class T, class U>
concept Relation = std::Predicate<R, T, U>;
或者也许
template <class R, class T, class U>
concept Relation = std::Predicate<R, T, U> && std::Predicate<R, U, T>;
甚至
template <class R, class T, class U>
concept Relation = std::Predicate<R, T, U> || std::Predicate<R, U, T>;
据我了解,类型T
和U
之间的relation是对(T, U)
上的二进制谓词。因此,对两个T
类型的对象或两个U
类型的对象进行评估是没有意义的。但是,给定的定义要求必须使用参数(T,T)
和(U,U)
来调用关系。
我的问题是 :这个Relation
概念的定义(看似错误)背后的动机是什么?
关于cppreference的说明指出
Relation(关系)概念指定R在表达式集和值类别为 T或U 编码的表达式集上定义二进制关系。
(重点是我的)
这听起来很奇怪:为什么在{strong> 任意组合中使用了 两种类型 的两个支持参数定义了通用Relation
概念 ?
一种可能是该概念用于指针和nullptr_t
的比较,以及迭代器和哨兵迭代器的比较。如果是这种情况,为什么将此概念称为Relation
,而不是更具体的名称,例如InterComparable
?只是误称吗?
答案 0 :(得分:4)
这是一个错误的称呼。据我所知,存在为StrictWeakOrder之类的东西提供语法要求,而没有语义要求的地方。
例如也考虑
template <class R, class T, class U>
concept Equivalence = std::Relation<R, T, U>;
//A relation r is an equivalence if
// - it is reflexive: for all x, r(x, x) is true;
// - it is symmetric: for all a and b, if r(a, b) is true then r(b, a) is true;
// - it is transitive: for all a, b and c, if r(a, b) and r(b, c) are both true then r(a, c) is true;