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 integralund signed_integralKonzepte 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 integralist gerecht is_integral_v. Die Zersetzung von signed_integralist 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 integralnicht nicht subsumieren signed_integral, sondern signed_integral tut subsume integral, da es alles enthält integraltut.
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_integralsubsumiert integral, <signed_integral> wrapperist 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> wrappernicht mindestens so eingeschränkt ist wie <signed_integral> wrapperdas 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_videntisch 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.