Aşağıdaki bilgiler güncel değil. En son Concepts Lite taslağına göre güncellenmesi gerekiyor.
Kısıtlama önerisinin 3. Bölümü , bunu makul derinlikte ele almaktadır.
Kavram önerisi , kısıtlamaların (yani kavramlar-lite) daha kısa bir zaman ölçeğinde geliştirilip uygulanabileceği umuduyla kısa bir süre için arka brülörlere konuldu ve şu anda en azından C ++ 14'te bir şey hedefleniyor. Kısıtlamalar önerisi, daha sonraki bir kavram tanımına yumuşak bir geçiş olarak hareket etmek üzere tasarlanmıştır. Kısıtlamalar , konsept önerisinin bir parçasıdır ve tanımında gerekli bir yapı taşıdır.
In C ++ için Konsept Kütüphaneleri Tasarım , Sutton ve Stroustrup aşağıdaki ilişkiyi göz önünde bulundurun:
Kavramlar = Kısıtlamalar + Aksiyomlar
Anlamlarını hızlı bir şekilde özetlemek için:
- Kısıtlama - Bir türün statik olarak değerlendirilebilir özelliklerinin üzerinde bir yüklem. Tamamen sözdizimsel gereksinimler. Alan soyutlaması değil.
- Aksiyomlar - Doğru olduğu varsayılan türlerin anlamsal gereksinimleri. Statik olarak kontrol edilmemiştir.
- Kavramlar - Algoritmaların argümanları üzerindeki genel, soyut gereksinimleri. Kısıtlamalar ve aksiyomlar açısından tanımlanmıştır.
Dolayısıyla, kısıtlamalara (sözdizimsel özellikler) aksiyomlar (anlamsal özellikler) eklerseniz, kavramlar elde edersiniz.
Kavramlar-Lite
Kavramlar-lite önerisi bize sadece ilk kısmı, kısıtlamaları getiriyor, ancak bu, tam teşekküllü kavramlara doğru önemli ve gerekli bir adım.
Kısıtlamalar
Kısıtlamalar tamamen sözdizimi ile ilgilidir . Derleme zamanında bir türün özelliklerini statik olarak ayırt etmenin bir yolunu sunarlar, böylece şablon argümanları olarak kullanılan türleri sözdizimsel özelliklerine göre kısıtlayabiliriz. Mevcut kısıtlamalar önerisinde, bunlar &&
ve gibi mantıksal bağlantılar kullanılarak önermeler hesabının bir alt kümesi ile ifade edilirler ||
.
Eylem halindeki bir kısıtlamaya bir göz atalım:
template <typename Cont>
requires Sortable<Cont>()
void sort(Cont& container);
Burada adında bir işlev şablonu tanımlıyoruz sort
. Yeni ekleme, gerekli cümledir . Require cümlesi, bu fonksiyon için şablon argümanları üzerinde bazı kısıtlamalar verir. Özellikle, bu kısıtlama, türün Cont
bir Sortable
tür olması gerektiğini söyler . Güzel bir şey, daha kısa bir biçimde şu şekilde yazılabilmesidir:
template <Sortable Cont>
void sort(Cont& container);
Şimdi Sortable
, bu işleve dahil edilmeyen herhangi bir şeyi iletmeye çalışırsanız, çıkarılan türün T
bir Sortable
tür olmadığını hemen söyleyen güzel bir hata alırsınız . Bunu C ++ 11'de yapmış olsaydınız , işlevin içindensort
kimseye anlam ifade etmeyen korkunç bir hata atmış olurdunuz .
Kısıtlama tahminleri, tür özelliklerine çok benzer. Bazı şablon argüman türünü alırlar ve size bunun hakkında bazı bilgiler verirler. Kısıtlamalar, türle ilgili aşağıdaki türden soruları yanıtlamaya çalışır:
- Bu tipte şu ve bu tür operatörler aşırı yüklenmiş mi?
- Bu türler bu işleç için işlenenler olarak kullanılabilir mi?
- Bu türün şu ve bu tür bir özelliği var mı?
- Bu sabit ifade buna eşit mi? (tür olmayan şablon argümanları için)
- Bu türün, o türü döndüren yada-yada adlı bir işlevi var mı?
- Bu tür, bu şekilde kullanılacak tüm sözdizimsel gereksinimleri karşılıyor mu?
Bununla birlikte, kısıtlamaların tür özelliklerinin yerini alması amaçlanmamıştır . Bunun yerine, el ele çalışacaklar. Bazı tip özellikleri artık kavramlar açısından ve bazı kavramlar tip özellikleri açısından tanımlanabilir.
Örnekler
Yani kısıtlamalarla ilgili önemli olan şey, anlambilimle bir nebze olsun ilgilenmemeleridir. Bazı iyi kısıtlama örnekleri şunlardır:
Equality_comparable<T>
: Türün ==
aynı türden her iki işlenenle de olup olmadığını kontrol eder .
Equality_comparable<T,U>
: ==
Verilen tiplerin sol ve sağ işlenenleri olup olmadığını kontrol eder
Arithmetic<T>
: Türün aritmetik bir tür olup olmadığını kontrol eder.
Floating_point<T>
: Türün kayan nokta türü olup olmadığını kontrol eder.
Input_iterator<T>
: Türün, bir girdi yineleyicisinin desteklemesi gereken sözdizimsel işlemleri destekleyip desteklemediğini kontrol eder.
Same<T,U>
: Verilen türün aynı olup olmadığını kontrol eder.
Tüm bunları GCC'nin özel bir kavram-lite yapısıyla deneyebilirsiniz .
Kavramların Ötesinde-Lite
Şimdi konseptler-lite önerisinin ötesindeki her şeye giriyoruz. Bu, geleceğin kendisinden bile daha fütüristik. Bundan sonra her şey muhtemelen biraz değişecek.
Aksiyomlar
Aksiyomlar tamamen anlambilimle ilgilidir . İlişkileri, değişmezleri, karmaşıklık garantilerini ve benzeri diğer şeyleri belirtirler. Bir örneğe bakalım.
İken Equality_comparable<T,U>
kısıt orada olduğunu söyleyecektir operator==
türlerini alır T
ve U
bu size ne anlama operasyon söylemez araçları . Bunun için aksiyoma sahip olacağız Equivalence_relation
. Bu aksiyom, bu iki türdeki nesneler operator==
vermekle karşılaştırıldığında true
, bu nesnelerin eşdeğer olduğunu söyler . Bu gereksiz görünebilir, ancak kesinlikle değildir. Bunun operator==
yerine bir operator<
. Bunu yaparsan kötü olursun ama yapabilirsin.
Başka bir örnek de Greater
aksiyomdur. İki tür nesnenin ve operatörlerle T
karşılaştırılabileceğini söylemek iyi ve iyidir , ancak bunlar ne anlama geliyor ? Aksiyomu IFF diyor sonra büyüktür sonra daha azdır . Önerilen spesifikasyon böyle bir aksiyom şuna benzer:>
<
Greater
x
y
y
x
template<typename T>
axiom Greater(T x, T y) {
(x>y) == (y<x);
}
Dolayısıyla aksiyomlar aşağıdaki soru türlerine cevap verir:
- Bu iki operatörün birbiriyle bu ilişkisi var mı?
- Bu tür ve benzeri türler için bu operatör bu anlama mı geliyor?
- Bu türdeki bu işlem bu karmaşıklığa sahip mi?
- Operatörün bu sonucu bunun doğru olduğunu mu ima ediyor?
Yani, tamamen türlerin anlambilimiyle ve bu türler üzerindeki işlemlerle ilgilenirler. Bunlar statik olarak kontrol edilemez. Bunun kontrol edilmesi gerekiyorsa, bir tür bir şekilde bu semantiğe bağlı olduğunu ilan etmelidir.
Örnekler
İşte aksiyomların bazı yaygın örnekleri:
Equivalence_relation
: İki nesne karşılaştırırsa ==
, eşdeğerdirler.
Greater
: Ne zaman x > y
, o zaman y < x
.
Less_equal
: Ne zaman x <= y
, o zaman !(y < x)
.
Copy_equality
: For x
and y
of type T
: eğer x == y
, kopya oluşturma T{x} == y
ile oluşturulan aynı türden yeni bir nesne ve yine de x == y
(yani, yıkıcı değildir).
Kavramlar
Artık kavramları tanımlamak çok kolay; bunlar sadece kısıtlamaların ve aksiyomların birleşimidir . Bir türün sözdizimi ve anlambilimine göre soyut bir gereksinim sağlarlar.
Örnek olarak şu Ordered
kavramı ele alalım :
concept Ordered<Regular T> {
requires constraint Less<T>;
requires axiom Strict_total_order<less<T>, T>;
requires axiom Greater<T>;
requires axiom Less_equal<T>;
requires axiom Greater_equal<T>;
}
Şablon türü için ilk nota olduğunu T
olmak Ordered
, aynı zamanda gereksinimlerini karşılaması gerekir Regular
kavram. Regular
Konsept tipi uslu olduğunu çok temel bir gereklilik olduğunu - bu, inşa tahrip kopyalanıp karşılaştırılabilir.
Bu şartların yanı sıra, Ordered
gerektirir T
tanışın tek kısıtlamayı ve dört belitleri:
- Kısıtlama: Bir
Ordered
türün bir operator<
. Bu statik olarak kontrol edildiğinden , var olması gerekir .
- Aksiyomlar: Tip
x
ve y
için T
:
x < y
kesin bir toplam sıralama verir.
- Ne zaman
x
büyüktür y
, y
küçüktür x
ve tam tersi.
- Ne zaman
x
küçüktür veya eşittir y
, y
daha az değildir x
ve tam tersi.
- Ne zaman
x
büyüktür veya eşittir y
, y
büyük değildir x
ve tam tersi.
Kısıtlamaları ve aksiyomları bu şekilde birleştirmek size kavramlar verir. Algoritmalarla kullanılmak üzere soyut türler için sözdizimsel ve anlamsal gereksinimleri tanımlarlar. Algoritmalar şu anda kullanılan türlerin belirli işlemleri destekleyeceğini ve belirli anlambilimlerini ifade edeceğini varsaymak zorundadır. Kavramlarla, gereksinimlerin karşılandığından emin olabileceğiz.
En son konsept tasarımında , derleyici yalnızca bir kavramın sözdizimsel gereksinimlerinin şablon argümanı tarafından yerine getirilip getirilmediğini kontrol edecektir. Aksiyomlar kontrol edilmeden bırakılır. Aksiyomlar, statik olarak değerlendirilemeyen (veya genellikle tamamen kontrol edilmesi imkansız olan) anlambilimlere işaret ettiğinden, bir türün yazarının, türlerinin bir kavramın tüm gereksinimlerini karşıladığını açıkça belirtmesi gerekir. Bu, önceki tasarımlarda konsept haritalama olarak biliniyordu ancak o zamandan beri kaldırıldı.
Örnekler
İşte bazı kavram örnekleri:
Regular
türler yapılandırılabilir, yok edilebilir, kopyalanabilir ve karşılaştırılabilir.
Ordered
türleri destekler operator<
ve katı bir toplam sıralama ve diğer sıralama anlamlarına sahiptir.
Copyable
türler kopyalanabilir, yok edilebilir ve x
eşitse y
ve x
kopyalanmışsa, kopya da eşittir y
.
Iterator
tipleri ilişkili olmalı türleri value_type
, reference
, difference_type
, ve iterator_category
kendilerini belli kavramları karşılaması gerekir ki. Ayrıca desteklemeli operator++
ve çıkarılabilir olmalıdırlar .
Kavramlara Giden Yol
Kısıtlamalar, C ++ 'nın tam kavramlar özelliğine doğru ilk adımdır. Çok önemli bir adımdır çünkü türlerin statik olarak uygulanabilir gereksinimlerini sağlarlar, böylece çok daha temiz şablon işlevleri ve sınıfları yazabiliriz. Şimdi bazı zorluklardan ve çirkinliklerinden std::enable_if
ve onun metaprogramlama arkadaşlarından kaçınabiliriz .
Bununla birlikte, kısıtlama önerisinin yapmadığı birkaç şey vardır:
Kavram tanımlama dili sağlamaz.
Kısıtlamalar kavram haritaları değildir. Kullanıcının, belirli kısıtlamaları karşılayan türlerine özel olarak açıklama eklemesine gerek yoktur. Statik olarak kontrol edilir ve kullanılan basit derleme zamanı dil özellikleri kullanılır.
Şablonların uygulanması, şablon argümanları üzerindeki kısıtlamalarla sınırlandırılmaz. Diğer bir deyişle, işlev şablonunuz, yapmaması gereken kısıtlı türde bir nesne ile herhangi bir şey yaparsa, derleyicinin bunu teşhis etme yolu yoktur. Tam özellikli bir konsept önerisi bunu yapabilir.
Kısıtlama önerisi, üzerine tam bir konsept önerisi getirilebilecek şekilde özel olarak tasarlanmıştır. Şansınız varsa, bu geçiş oldukça yumuşak bir yolculuk olmalıdır. Kavramlar grubu, C ++ 14 için (veya kısa süre sonra teknik bir raporda) kısıtlamalar getirmeye çalışırken, tüm kavramlar bazen C ++ 17 civarında ortaya çıkmaya başlayabilir.