Im latest paper on concepts N3701 gibt es das folgende Beispiel mit dem sort
Algorithmus:Warum Sortierkonzept erfordert total geordneten Werttyp, während Std :: Sort nur "weniger als" vergleichbar erfordert?
template<typename Cont>
requires Sortable<Cont>()
void sort(Cont& cont)
wo Sortable
Konzept als
template<typename T>
concept bool Sortable()
{
return Permutable_container<T>() && Totally_ordered<Value_type<T>>();
}
wo Totally_ordered
, nicht überraschend, als
template<typename T>
constexpr bool Totally_ordered()
{
return Weakly_ordered<T>() && Equality_comparable<T>();
}
definiert ist
und wiederum Equality_comparable
ist definiert als
template<typename T>
constexpr bool Equality_comparable()
{
return requires(T a, T b) {
{a == b} -> bool;
{a != b} -> bool;
};
}
Ich fand nicht die Definition von Weakly_ordered
, aber ich glaube, es sollte wie folgt aussehen (bin ich richtig?)
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;
};
}
Unterm Strich in dieser Definition, wenn ich will zu sortieren std::vector<T>
, ich brauche T alle Vergleichsoperatoren <
, bieten <=
, >
, >=
, ==
, !=
. Während der gesamten Lebensdauer von C++, std::sort
, wird jedoch nur der erforderliche Operator <
benötigt! Hier ist, was cppreference sagt über std::sort
:
Sortiert die Elemente im Bereich [first, last) in aufsteigender Reihenfolge. Es ist nicht garantiert, dass die Reihenfolge der gleichen Elemente beibehalten wird. Die erste Version verwendet Operator <, um die Elemente zu vergleichen, die zweite Version verwendet das angegebene Vergleichsfunktionsobjekt comp.
Also, was bedeutet, dass in Zukunft C++ mit Konzepten für v
vom Typ std::vector<T>
wo T
nur operator<
bietet, std::sort(v.begin(), v.end())
kompilieren, während std::sort(v)
nicht? Das klingt verrückt.
Ich habe dies in der aktuellen ranges-v3 implementation von Eric Niebler überprüft, und es funktioniert genauso wie ich beschrieben habe. Code wird nicht kompiliert, wenn nicht alle Operatoren bereitgestellt werden.
Siehe auch Siehe auch: https://github.com/ericniebler/range-v3/issues/271
Ich habe dies in der aktuellen Reichweiten-v3-Implementierung von Eric Niebler (https://github.com/ericnebler/range-v3) überprüft, und es funktioniert genau wie ich beschrieben habe. Code wird nicht kompiliert, wenn nicht alle Operatoren bereitgestellt werden. Diese Implementierung erfordert jedoch "IndirectCallableRelation". – Mikhail
@Mikhail: Ich lese weiter in der Spezifikation. –
Danke. Siehe auch https://github.com/ericnebler/range-v3/issues/271 – Mikhail