In the latest paper on concepts N3701, there is the following example with the sort
algorithm:
template<typename Cont>
requires Sortable<Cont>()
void sort(Cont& cont)
where Sortable
concept is defined as
template<typename T>
concept bool Sortable()
{
return Permutable_container<T>() && Totally_ordered<Value_type<T>>();
}
where Totally_ordered
, not surprisingly, is defined as
template<typename T>
constexpr bool Totally_ordered()
{
return Weakly_ordered<T>() && Equality_comparable<T>();
}
and in turn Equality_comparable
is defined as
template<typename T>
constexpr bool Equality_comparable()
{
return requires(T a, T b) {
{a == b} -> bool;
{a != b} -> bool;
};
}
I didn't find the definition of Weakly_ordered
, but I believe it should look like this (am I right?)
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;
};
}
Bottom line, in this definition, if I want to sort std::vector<T>
, I need T to provide all comparison operators <
, <=
, >
, >=
, ==
, !=
. However, during the whole life of C++, std::sort
only required operator <
to be provided! Here is what cppreference says about std::sort
:
Sorts the elements in the range [first, last) in ascending order. The order of equal elements is not guaranteed to be preserved. The first version uses operator< to compare the elements, the second version uses the given comparison function object comp.
So what, does that mean that in future C++ with concepts, for v
of type std::vector<T>
where T
provides only operator<
, std::sort(v.begin(), v.end())
will compile, while std::sort(v)
will not? This sounds crazy.
I checked this in the current ranges-v3 implementation by Eric Niebler, and it works just like I described. Code does not compile unless all operators are provided.
See also related discussion: https://github.com/ericniebler/range-v3/issues/271