Kavramlar (C++) - Concepts (C++)

Kavramlar , C++ programlama dili tarafından sağlanan şablonlar özelliğinin bir uzantısıdır . Kavramlar , derleme zamanında değerlendirilen şablon parametrelerine göre Boolean tahminleri olarak adlandırılır . Bir kavram bir şablonla ( sınıf şablonu, işlev şablonu veya bir sınıf şablonunun üye işlevi ) ilişkilendirilebilir, bu durumda bir kısıtlama görevi görür : şablon parametreleri olarak kabul edilen argümanlar kümesini sınırlar.

Başlangıçta C++11 önerilerine dayanan orijinal kavramlar belirtimi, resmi olarak C++20'nin gerekli bir parçası olmadan önce birçok kez revize edildi .

Ana kullanımlar

Kavramların ana kullanımları şunlardır:

  • şablon programlamaya tip denetiminin tanıtılması
  • başarısız şablon örneklemeleri için basitleştirilmiş derleyici teşhisi
  • tip özelliklerine dayalı olarak fonksiyon şablonu aşırı yüklemelerini ve sınıf şablonu uzmanlıklarını seçme
  • kısıtlayıcı otomatik tür kesintisi

Örnek: EşitlikKarşılaştırılabilir

Aşağıda, konsept etkin C++ standart kitaplığından (ayrı bir ISO Teknik Spesifikasyonu, ISO/IEC DTS 21425) "EqualityComparable" kavramının bir beyanı yer almaktadır. Bu kavram her tür tarafından yerine getirildiği Tiçin, öyle ki SolDeğerler a ve bÇeşidi T, ifadeler a==bve a!=bderleme ve bunların sonuçları bir tipe dönüştürülebilir olduğunu karşılar konsepti "Boole":

template<typename T>
concept EqualityComparable = requires(T a, T b) {
    { a == b } -> std::same_as<bool>;
    { a != b } -> std::same_as<bool>;
};

Bu kavramla sınırlandırılmış bir fonksiyon şablonu aşağıdaki gibi bildirilebilir:

void f(const EqualityComparable auto&); // constrained function template declaration

veya

template <EqualityComparable T>
void f(const T&); // constrained function template declaration

Ve her zamanki gibi çağrılabilir:

f(42); // OK, int satisfies EqualityComparable

Derleyici teşhisi

Bir programcı, şablonun gereksinimlerini karşılamayan bir şablon argümanı kullanmaya çalışırsa, derleyici bir hata üretecektir. Kavramlar kullanılmadığında, bu tür hataların anlaşılması genellikle zordur, çünkü hata çağrı bağlamında değil, daha çok türün kullanıldığı dahili, genellikle derinlemesine iç içe geçmiş bir uygulama bağlamında bildirilir.

Örneğin, ilk iki argümanının rastgele erişimli yineleyiciler olmasını gerektirir . Bir bağımsız değişken bir yineleyici değilse veya farklı bir kategorinin yineleyicisiyse, parametreleri çift yönlü yineleyiciler olarak kullanılmaya çalışıldığında bir hata oluşur : std::sortstd::sort

std::list<int> l = {2, 1, 3};
std::sort(l.begin(), l.end());

Kavramsız tipik derleyici tanılaması, iki yineleyiciyi çıkarmaya çalışan bir ifadenin derlenmemesiyle başlayan 50 satırdan fazla çıktıdır:

In instantiation of 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = std::_List_iterator<int>; _Compare = __gnu_cxx::__ops::_Iter_less_iter]':
 error: no match for 'operator-' (operand types are 'std::_List_iterator<int>' and 'std::_List_iterator<int>')
 std::__lg(__last - __first) * 2,

[..]

Kavramlar kullanılırsa hata, çağrı bağlamında algılanabilir ve raporlanabilir:

error: cannot call function 'void std::sort(_RAIter, _RAIter) [with _RAIter = std::_List_iterator<int>]'
note:   concept 'RandomAccessIterator()' was not satisfied

Aşırı yük çözünürlüğü

Kavramlar, SFINAE ve etiket gönderimine alternatif olarak, şablon argümanlarının özelliklerine dayalı olarak fonksiyon şablonu aşırı yüklemelerini ve sınıf şablonu uzmanlıklarını seçmek için kullanılabilir . Bir argüman birden fazla kavramı karşılıyorsa, daha kısıtlı kavramla ilişkili aşırı yükleme seçilir.

Tür kesintisi

Değişken bildirimlerinde ve işlev dönüş türlerinde sınırlandırılmamış tür kesinti yer tutucusu yerine kavramlar kullanılabilir : auto

auto     x1 = f(y); // the type of x1 is deduced to whatever f returns
Sortable auto x2 = f(y); // the type of x2 is deduced, but only compiles if it satisfies Sortable

Uygulama durumu

ISO/IEC TS 19217:2015'te belirtilen TS kavramları, GCC 6'da deneysel bir özellik olarak uygulanmaktadır . C++20 kavramları GCC 10 , MSVC 19.30 ve Clang 10'da tam olarak uygulanmaktadır .

Tarih

Halk arasında "C ++ 0x Kavramları" olarak bilinen Kavramları farklı bir formu, geçici işçi kağıt kabul edildi C ++ 11 ancak dahil kavramların kendileri "C ++ 0x Kavramlar" ek olarak 2009 yılında çıkarıldı kavramı haritalar (kabul etmek konsepti "Yığın" için, örneğin, mümkün yapabilir bir özellik , otomatik gibi "Yığın" operasyonları haritalama farklı adlandırılmış üzerinde operasyonlara gibi ve) aksiyomlardan (örneğin semantik özelliklerini belirlemek için bir tesis derleyicinin bu özelliklerden kanıt olmadan yararlanmasına izin veren ilişkisellik veya değişmelilik). std::vectorpush()std::vectorpush_back()

Bu terk edilmiş teklifin aksine, Concepts'in C++20 sürümü bazen "Concepts Lite" olarak anılır.

Mart 2016'daki C++ standartları komitesi toplantısında, evrim çalışma grubu, Concepts'i ana hat C++17 standardıyla birleştirmek için harekete geçti, ancak önerge tam komitede reddedildi.

Concepts v1, C++20 taslağıyla birleştirildi .

Kavramlara bağlı Range özelliğinin "The One Range" versiyonu da C++20 ile birleştirildi .

Ayrıca bakınız

Notlar

  1. ^ "GCC 6 Sürüm Serisi - Değişiklikler, Yeni Özellikler ve Düzeltmeler" .
  2. ^ "C++ derleyici desteği (gcc)" .
  3. ^ "C++ derleyici desteği" .
  4. ^ "Clang'da C++ Desteği" .
  5. ^ Bjarne Stroustrup (22 Temmuz 2009). "C++0x "Kavramları Kaldır" Kararı" . Doktor Dobbs .
  6. ^ Andrew Sutton (24 Şubat 2013). "Kavramlar Lite: Tahminlerle Şablonları Sınırlamak" . isocpp.org.
  7. ^ Honermann, Tom (6 Mart 2016). "Neden Concepts C++17'yi yapmadı" . honermann.net.
  8. ^ "2017 Toronto ISO C++ Komitesi Tartışma Konusu (C++20'deki Kavramlar; Eşyordamlar, Aralıklar ve Ağ Oluşturma TS'leri yayınlandı): cpp" .

Referanslar

Dış bağlantılar