Kavramlar ve şablon kısıtlamaları arasındaki farklar nelerdir?


96

C ++ tam kavram önerisi ile şablon kısıtlamaları arasındaki anlamsal farklılıkların neler olduğunu bilmek istiyorum (örneğin, Dlang'da görünen kısıtlamalar veya C ++ 1y için yeni kavramlar-lite önerisi ).

Şablon kısıtlamalarının yapamadığından daha fazlasını yapabilen tam teşekküllü kavramlar nelerdir?



4.8 Kavramları Tasarlamak'ı hatırlıyordum , ancak aslında kavramların kısıtlamaları nasıl artırdığına dair pek fazla liste yok. Herhangi bir şey varsa, Googling kavramları, teklifin kısıtlamalarını daha iyi anladıktan sonra artık kolayca tespit edilebilen bazı farklılıkları ortaya çıkarabilir.
chris

IMHO kavramları okunabilirliği artırır ve uzun zaman önce Alexander Stepanov'un 'Elements of Programming'de talep ettiği gibi daha net programatik yetenekler sağlar. Lite öneri, şu anda gerekli olan tuhaf enable_if türü kısıtlamaların yükünü hafifletmek için buna doğru bir harekettir. Genel programlama için ne kadar erken olursa o kadar iyidir.
dirvine

Yanıtlar:


136

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:

  1. Kısıtlama - Bir türün statik olarak değerlendirilebilir özelliklerinin üzerinde bir yüklem. Tamamen sözdizimsel gereksinimler. Alan soyutlaması değil.
  2. Aksiyomlar - Doğru olduğu varsayılan türlerin anlamsal gereksinimleri. Statik olarak kontrol edilmemiştir.
  3. 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 Contbir Sortabletü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 Tbir Sortabletü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:

  1. Bu tipte şu ve bu tür operatörler aşırı yüklenmiş mi?
  2. Bu türler bu işleç için işlenenler olarak kullanılabilir mi?
  3. Bu türün şu ve bu tür bir özelliği var mı?
  4. Bu sabit ifade buna eşit mi? (tür olmayan şablon argümanları için)
  5. Bu türün, o türü döndüren yada-yada adlı bir işlevi var mı?
  6. 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 Tve Ubu 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 Greateraksiyomdur. İki tür nesnenin ve operatörlerle Tkarşı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:><Greaterxyyx

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:

  1. Bu iki operatörün birbiriyle bu ilişkisi var mı?
  2. Bu tür ve benzeri türler için bu operatör bu anlama mı geliyor?
  3. Bu türdeki bu işlem bu karmaşıklığa sahip mi?
  4. 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 xand yof type T: eğer x == y, kopya oluşturma T{x} == yile 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 Orderedkavramı 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 Tolmak Ordered, aynı zamanda gereksinimlerini karşılaması gerekir Regularkavram. RegularKonsept 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, Orderedgerektirir Ttanışın tek kısıtlamayı ve dört belitleri:

  • Kısıtlama: Bir Orderedtürün bir operator<. Bu statik olarak kontrol edildiğinden , var olması gerekir .
  • Aksiyomlar: Tip xve yiçin T:
    • x < y kesin bir toplam sıralama verir.
    • Ne zaman xbüyüktür y, yküçüktür xve tam tersi.
    • Ne zaman xküçüktür veya eşittir y, ydaha az değildir xve tam tersi.
    • Ne zaman xbüyüktür veya eşittir y, ybüyük değildir xve 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.

  • Orderedtürleri destekler operator<ve katı bir toplam sıralama ve diğer sıralama anlamlarına sahiptir.

  • Copyabletürler kopyalanabilir, yok edilebilir ve xeşitse yve xkopyalanmışsa, kopya da eşittir y.

  • Iteratortipleri ilişkili olmalı türleri value_type, reference, difference_type, ve iterator_categorykendilerini 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_ifve onun metaprogramlama arkadaşlarından kaçınabiliriz .

Bununla birlikte, kısıtlama önerisinin yapmadığı birkaç şey vardır:

  1. Kavram tanımlama dili sağlamaz.

  2. 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.

  3. Ş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.


5
Concept-lite'ın şablonun kendisinin uygulanmasına karşı kısıtlamaları kontrol etmediği unutulmamalıdır. Dolayısıyla, herhangi bir DefaultConstructable'ın kullanılabileceğini iddia edebilirsiniz, ancak derleyici kazara bir kopya oluşturucuyu kullanmanızı engellemez. Daha tam özellikli bir konsept önerisi olur.
Nicol Bolas

24
Bu bir ilk taslak mı ?!
Nicol Bolas

2
@sftrabbit, çok iyi cevap. Ama bir sorum var: Bir derleyici, bir türün kavramın anlamsal gereksinimlerini karşılayıp karşılamadığını nasıl kontrol eder?
Rayniery

1
'Aksiyomlar' çalışma sırasında kontrol edilecek mi (çok fazla belirsizlikle) yoksa sadece bir tür vaat etiketleri olarak mı hizmet edecekler?
Red XIII

4
@ScarletAmaranth: Çünkü sonlu sınırlı zamanda otomatik olarak bir teoremi ispatlamaya indirgenir. Bunun önünde iki engel vardır: 1. Sonlu sınırlı zamanda herhangi bir teoremi kanıtlamak, teoride son derece zor ve mevcut teknoloji ile imkansızdır. 2. İspat başka aksiyomlara dayanmadıkça bir aksiyomu ispatlayamazsınız. (Bu durumda matematiksel olarak "aksiyom değil" olur) Bu aksiyomlar, derleyiciye "Elbette, yararlı olduğunu düşünürseniz karşılaştırmayı tersine çevirebilirsiniz ..." veya "Evet, bir kesişimde kullanılan bir BoşSet her zaman aynı sonucu verir. "
Laurent LA RIZZA


4

2 sentim:

  1. Concept-lite önerisi, şablon uygulamasının "tür denetimi" yapmak için tasarlanmamıştır . Yani, Concepts-lite, şablon somutlaştırma sitesinde (kavramsal olarak) arayüz uyumluluğunu sağlayacaktır. Makaleden alıntı: "kavramlar lite, şablon argümanlarını kısıtlamak için tahminlerin kullanımına izin veren bir C ++ uzantısıdır". Ve bu kadar. Şablon gövdesinin yüklemlere karşı (tek başına) kontrol edileceğini söylemez. Bu muhtemelen, kavramlar-lite hakkında konuşurken birinci sınıf arketipler kavramı olmadığı anlamına gelir . Archtypes, eğer doğru hatırlıyorsam, kavram ağırlıklı tekliflerde şablonun uygulanmasını tatmin etmek için daha azını ve fazlasını sunmayan türlerdir .

  2. kavramlar-lite, derleyici tarafından desteklenen bir miktar sözdizimi hilesi ile yüceltilmiş constexpr işlevlerini kullanır. Arama kurallarında değişiklik yok.

  3. Programcıların kavram haritaları yazması gerekmez.

  4. Son olarak, tekrar alıntı yaparak "Kısıtlamalar önerisi, anlambilimin spesifikasyonuna veya kullanımına doğrudan değinmez; yalnızca sözdizimini kontrol etmeyi hedefler." Bu, aksiyomların kapsam dahilinde olmadığı anlamına gelir (şimdiye kadar).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.