Как онлайн-черновик C++, так и 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
является бинарным предикатом для пар (T, U)
. Таким образом, нет смысла оценивать отношение двух объектов типа T
или двух объектов типа U
. Однако данное определение требует, чтобы отношение можно было вызывать с аргументами (T,T)
и (U,U)
.
Мой вопрос: какова мотивация этого (кажущегося неверным) определения концепции Relation
?
Объяснение, данное на cppreference, гласит, что
Концепция Relation указывает, что R определяет бинарное отношение над набором выражений, тип и категория значений которых кодируются либо T, либо U.
(выделено мной)
Мне это кажется странным: почему общая концепция Relation
определяется двумя вспомогательными аргументами двух типов, используемыми в любой комбинации?
Одна возможность может заключаться в том, что эта концепция используется для сравнения указателей и nullptr_t
, а также для сравнения итераторов и итераторов-стражей. Если это так, то почему это понятие называется Relation
, а не чем-то более конкретным, например, InterComparable
? Это просто неправильное название?
Predicate
уже является отношением, которое вы ожидаете.Relation
позволяет расширить набор типов, так чтоRelation<R, A, B>
может быть прочитано какPredicate<R, A U B, A U B>
(с U в качестве объединения для набора). - person Jarod42   schedule 23.05.2019