В последней статье по концепциям 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, чтобы предоставить все операторы сравнения <
, <=
, >
, >=
, ==
, !=
, Однако в течение всей жизни С++ std::sort
должен быть предоставлен только оператор <
! Вот что cppreference говорит о std::sort
:
Сортирует элементы в диапазоне [первый, последний] в порядке возрастания. порядок равных элементов не гарантируется. Первый версия использует оператор < для сравнения элементов, вторая версия использует данный объект сравнения comp comp.
Итак, что это значит, что в будущем С++ с концепциями для v
типа std::vector<T>
, где T
предоставляет только operator<
, std::sort(v.begin(), v.end())
будет компилироваться, а std::sort(v)
не будет? Это звучит безумно.
Я проверил это в текущей версии range-v3 от Эрика Ниблера, и он работает так, как я описал. Код не компилируется, если не указаны все операторы.
См. также соответствующее обсуждение: https://github.com/ericniebler/range-v3/issues/271