C ++ 20 verfügt über einen Mechanismus zum Entscheiden, wann eine bestimmte eingeschränkte Entität "stärker eingeschränkt" ist als eine andere. Das ist keine einfache Sache.
Dies beginnt mit dem Konzept, eine Einschränkung in ihre atomaren Komponenten zu zerlegen, ein Prozess, der als Einschränkungsnormalisierung bezeichnet wird . Es ist groß und zu komplex, um hier darauf einzugehen, aber die Grundidee ist, dass jeder Ausdruck in einer Einschränkung rekursiv in seine atomaren konzeptuellen Teile zerlegt wird, bis Sie einen Komponenten-Unterausdruck erreichen, der kein Konzept ist.
Schauen wir uns vor diesem Hintergrund an, wie die integral
und signed_integral
Konzepte definiert sind :
template<class T>
concept integral = is_integral_v<T>;
template<class T>
concept signed_integral = integral<T> && is_signed_v<T>;
Die Zersetzung von integral
ist gerecht is_integral_v
. Die Zersetzung von signed_integral
ist is_integral_v && is_signed_v
.
Nun kommen wir zum Konzept der Constraint-Subsumtion . Es ist etwas kompliziert, aber die Grundidee ist, dass eine Einschränkung C1 eine Einschränkung C2 "subsumiert", wenn die Zerlegung von C1 jeden Unterausdruck in C2 enthält. Wir können sehen , dass integral
nicht nicht subsumieren signed_integral
, sondern signed_integral
tut subsume integral
, da es alles enthält integral
tut.
Als nächstes kommen wir zur Bestellung von eingeschränkten Entitäten:
Eine Deklaration D1 ist mindestens so eingeschränkt wie eine Deklaration D2, wenn * D1 und D2 beide eingeschränkte Deklarationen sind und die zugehörigen Einschränkungen von D1 die von D2 subsumieren; oder * D2 hat keine zugehörigen Einschränkungen.
Weil signed_integral
subsumiert integral
, <signed_integral> wrapper
ist das "mindestens so eingeschränkt" wie das <integral> wrapper
. Das Gegenteil ist jedoch nicht der Fall, da die Subsumtion nicht umkehrbar ist.
In Übereinstimmung mit der Regel für "eingeschränktere" Entitäten:
Eine Deklaration D1 ist stärker eingeschränkt als eine andere Deklaration D2, wenn D1 mindestens so eingeschränkt ist wie D2 und D2 nicht mindestens so eingeschränkt ist wie D1.
Da das <integral> wrapper
nicht mindestens so eingeschränkt ist wie <signed_integral> wrapper
das letztere, wird das letztere als stärker eingeschränkt angesehen als das erstere.
Und daher gewinnt die eingeschränktere Deklaration, wenn beide zutreffen könnten.
Beachten Sie, dass die Regeln für die Subsumtion von Einschränkungen aufhören, wenn ein Ausdruck gefunden wird, der kein a ist concept
. Wenn Sie dies getan haben:
template<typename T>
constexpr bool my_is_integral_v = std::is_integral_v<T>;
template<typename T>
concept my_signed_integral = my_is_integral_v<T> && std::is_signed_v<T>;
In diesem Fall my_signed_integral
würde nicht subsumieren std::integral
. Obwohl C ++ my_is_integral_v
identisch definiert ist std::is_integral_v
, weil es kein Konzept ist, können die Subsumtionsregeln von C ++ nicht durchsehen, um festzustellen, ob sie identisch sind.
Die Subsumtionsregeln ermutigen Sie daher, Konzepte aus Operationen auf atomaren Konzepten zu erstellen.