В последнем документе о концепциях N3701 , есть следующий пример с алгоритмом sort
:
template<typename Cont>
requires Sortable<Cont>()
void sort(Cont& cont)
где понятие Sortable
определяется как
template<typename T>
concept bool Sortable()
{
return Permutable_container<T>() && Totally_ordered<Value_type<T>>();
}
где Totally_ordered
, что неудивительно, определяется как
template<typename T>
constexpr bool Totally_ordered()
{
return Weakly_ordered<T>() && Equality_comparable<T>();
}
и, в свою очередь, Equality_comparable
определяется как
template<typename T>
constexpr bool Equality_comparable()
{
return requires(T a, T b) {
{a == b} -> bool;
{a != b} -> bool;
};
}
Я не нашел определения Weakly_ordered
, но я думаю, что оно должно выглядеть так (я прав?)
template<typename T>
constexpr bool Weakly_ordered()
{
return requires(T a, T b) {
{a < b} -> bool;
{a <= b} -> bool;
{a > b} -> bool;
{a >= b} -> bool;
};
}
Суть в том, что в этом определении, если я хочу отсортировать std::vector<T>
, мне нужно, чтобы T предоставил все операторы сравнения <
, <=
, >
, >=
, ==
, !=
. Однако на протяжении всей жизни C++ std::sort
требовался только оператор <
! Вот что cppreference говорит о std::sort
:
Сортирует элементы в диапазоне [первый, последний) в порядке возрастания. Порядок равных элементов не гарантируется. Первая версия использует оператор‹ для сравнения элементов, вторая версия использует данный объект функции сравнения comp.
Так что же, означает ли это, что в будущем C++ с концепциями для v
типа std::vector<T>
, где T
предоставляет только operator<
, std::sort(v.begin(), v.end())
будет компилироваться, а std::sort(v)
— нет? Это звучит безумно.
Я проверил это в текущей реализации ranges-v3 Эрика Ниблера, и все работает так, как я описал. . Код не компилируется, если не указаны все операторы.
См. также соответствующее обсуждение: https://github.com/ericniebler/range-v3/issues/ 271а>