C ++ 20, belirli bir kısıtlanmış varlığın diğerinden "daha kısıtlı" olduğuna karar verme mekanizmasına sahiptir. Bu basit bir şey değil.
Bu, bir kısıtlamayı atom bileşenlerine ayırma kavramı ile başlar; bu, kısıt normalizasyonu adı verilen bir süreçtir . Buraya girmek çok büyük ve karmaşık, ancak temel fikir, bir kısıtlamadaki her ifadenin, kavram olmayan bir bileşen alt ifadesine ulaşıncaya kadar özyinel olarak atomik kavramsal parçalarına ayrılmasıdır.
Öyleyse, integral
ve signed_integral
kavramlarının nasıl tanımlandığına bakalım :
template<class T>
concept integral = is_integral_v<T>;
template<class T>
concept signed_integral = integral<T> && is_signed_v<T>;
Ayrışması integral
sadece is_integral_v
. Ayrışması signed_integral
DİR is_integral_v && is_signed_v
.
Şimdi, kısıtlama toplamı kavramına geliyoruz . Bu biraz karmaşıktır, ancak temel fikir, eğer C1'in ayrışması C2'deki her alt ifadeyi içeriyorsa C1 kısıtlamasının C2 sınırını "tükettiği" söylenir. Biz görebilirsiniz integral
subsume vermez signed_integral
, ama signed_integral
yapar subsume integral
her şey içerdiğinden, integral
yapar.
Ardından, kısıtlı varlıklar sipariş etmeye geliyoruz:
* D1 ve D2'nin her ikisi de kısıtlanmış bildirimlerse ve D1'in ilişkili kısıtlamaları D2'ninkileri içeriyorsa, D1 bildirimi en azından D2 bildirimi kadar sınırlıdır; veya * D2 ile ilişkili herhangi bir kısıtlama yoktur.
Çünkü signed_integral
subsumes integral
, <signed_integral> wrapper
olarak "en azından kısıtlanmış" <integral> wrapper
. Ancak, tersinirlik, toplamın tersinir olmaması nedeniyle doğru değildir.
Bu nedenle, "daha kısıtlı" varlıklar kuralına uygun olarak:
D1, en azından D2 kadar kısıtlı olduğunda ve D2, en azından D1 kadar kısıtlı olmadığında, D1 bildirimi, başka bir D2 bildiriminden daha kısıtlıdır.
Yana <integral> wrapper
olarak kısıtlı gibi en az değildir <signed_integral> wrapper
, ikincisi daha eski daha kısıtlı olarak kabul edilmektedir.
Bu nedenle, ikisi de başvurabildiğinde, daha kısıtlı beyan kazanır.
Kısıtlama kurallarının, a olmayan bir ifadeyle karşılaşıldığında durduğunu unutmayın concept
. Eğer bunu yaptıysanız:
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>;
Bu durumda, my_signed_integral
olmaz subsume std::integral
. Her ne kadar my_is_integral_v
aynı olarak tanımlansa da , std::is_integral_v
bir kavram olmadığından, C ++ 'ın toplamlama kuralları aynı olduklarını belirlemek için akranlarından geçemez.
Böylece, toplama kuralları, atomik kavramlar üzerindeki işlemlerden kavramlar oluşturmanızı teşvik eder.