Yazılımın geliştirilmesinde aptal: normal veri türleri

Adanali

Active member
Yazılımın geliştirilmesinde aptal: normal veri türleri


  1. Yazılımın geliştirilmesinde aptal: normal veri türleri

Normal tip konsept, Standart Model Kütüphanesi (STL) Alexander Stepanov'un babasına dayanmaktadır. Normal tip, entegre bir veri türü olarak davranan kişiselleştirilmiş bir veri türüdür.










Rainer Grimm yıllardır yazılım mimarı, ekip ve eğitim müdürü olarak çalıştı. C ++ programlama dilleri, Python ve Haskell hakkında makaleler yazmayı seviyor, ancak uzman konferanslarla konuşmayı da seviyor. Modern C ++ blogunda, C ++ tutkusuyla yoğun bir şekilde ilgileniyor.













Beton tipi (beton tipi) normal tipte (normal tip) kesinlikle ilişkilidir. Bu nedenle bu makaleye özel konseptle başlamak istiyorum.

Çimento türü

  • A Çimento türü Çekirdek C ++ yönergelerine göre “Bir sınıfın en basit türü“. Değer türü genellikle tanımlanır (değer türü) ve bir tür hiyerarşisinin parçası değildir.
  • A normal adam Bu bir tür veri “İnt gibi kopyala“Ve sonra kopyalayıp atayın, eşitliği ve sırayı destekleyin.
İşte C ++ Çekirdek Yönergelerinden başka yorumlar:

C.10: Sınıf hiyerarşilerine kıyasla çimento türlerini tercih edin



Bir sınıf hiyerarşisi için uygulamanız yoksa belirli tür tercih edilir. Somut bir tipin uygulanması çok daha kolay, daha küçük ve daha hızlı. Miras, sanallık, referanslar veya ellerle ilgilenmek, hafızanın tahsisi ve onaylanması bile gerekli değildir. Sanal keşif yoktur ve bu nedenle aşırı yük yoktur.

Kısa kılmak için: İşte öpücük prensibi (basit, aptal tutun). Veri türü bir değer gibi davranır.

C.11: Çimento türlerini düzenli hale getirin

Normal türlerin (IS) anlaşılması daha kolaydır. Kendi içlerinde sezgiseller. Bu, belirli bir türünüz varsa, normal bir türe dönüştürmeniz gerektiği anlamına gelir. Gibi entegre veri türleri int VEYA double Düzenlidirler, ancak aynı zamanda konteynerler std::string, std::vector VEYA std::unordered_map.

Şimdi normal türler hakkında daha ayrıntılı olarak gideceğim.

Normal adam


Düzenli türler kavramı STL'nin babası Alexander Stepanov'a dayanmaktadır. “Jenerik Programlama Vakıfları” makalesinde düzenli türler hakkındaki fikirlerini anlattı ve onları “Programlama Elemanları” kitabında mükemmelleştirdi.

Normal bir veri türünden nasıl yararlanırlar? Alexander Stepanov, “Programlama Elemanları” adlı kitabında cevap veriyor: Bir türün hesaplama temeline dahil edilmesi, nesneleri veri yapılarına konumlandırmamıza ve nesneleri bir veri yapısından diğerine kopyalamak için algoritmaları kullanmamıza izin veren bir dizi prosedür vardır. Kullanımları davranışın düzenliliğini ve dolayısıyla birlikte çalışabilirliği garanti ettiğinden, normal bir normal olan tipi diyoruz.

Bunu kısaltmak için: Düzenli türler, veri yapılarında ve entegre türler olarak algoritmalarda sezgisel olarak ifade edilir.

Normal bir veri türü nasıl sezgisel olabilir? “Jenerik Programlamanın Temelleri” belgesine göre, bir tür düzenli veri aşağıdakileri desteklemelidir:









Bu tablonun işlemleri tanıdık görünmelidir. C ++ 20 konsepte sahip std::regular.

Kavram std::regular


Kavram std::regular Stepanov'un normal veri türü fikri çok benzer. Esasen hareket semantiğini içerir.

C ++ 20'de, normal türler kavramı iki kavramla rafine edilmiştir: std::semiregular VE std::regular.

Bir tür yarı -rugüler veri X Altı kuralını desteklemelidir (son makalem “C ++ Programlama Dili: Sıfır veya /Altı” Kuralına bakın) ve değiştirilebilir.

Bir tür yarı -gelişmiş X verileri altı kuralı desteklemeli (en son makalem “Sıfır/Altı” kuralına bakın) ve değiştirilebilir olmalıdır:

  • Varsayılan üretici: X()
  • Kopya Kopya: X(const X&)
  • Kopya Atama: X& operator = (const X&)
  • Üreticiyi hareket ettirin: X(X&&)
  • Görevi hareket ettirin: X& operator = (X&&)
  • Yıkım: ~X()
  • Değiştirilebilir: swap(X&, X&)
Yalnızca bir özellik vardır ve bir tür yarı -ortaya çıkıntılı X verileri düzenli hale gelir.

Bir tür normal veri düzenlidir ve eşitlik ile karşılaştırılabilir:

  • Eşitlik Operatörü: operator == (const X&, const X&)
  • Eşitsizlik Operatörü: operator != (const X&, const X&)
Kavram std::regular Üç kavram üzerine C ++ 20'ye dayanmaktadır std::movable, std::copyable VE std::semiregular.



template<class T>
concept movable = is_object_v<T> && move_constructible<T> &&
assignable_from<T&, T> && swappable<T>;

template<class T>
concept copyable = copy_constructible<T> && movable<T>
&& assignable_from<T&, const T&>;

template<class T>
concept semiregular = copyable<T> && default_constructible<T>;

template<class T>
concept regular = semiregular<T> && equality_comparable<T>;


Kavram std::movable Std :: IS_OBJECT türlerinin işlevine dayanır. İşte cppReference.com'un olası bir uygulaması.



template< class T>
struct is_object : std::integral_constant<bool,
std::is_scalar<T>::value ||
std::is_array<T>::value ||
std::is_union<T>::value ||
std::is_class<T>::value> {};


Konsept de temeldir std::movable Kavramlara std::move_constructible VE std::assignable_from. Kavramların diğer tüm bileşenleri std::copyable VE std::semiregular Ayrıca C ++ 20 kavramlarıdır.

Kavramlar hakkında daha fazla bilgi önceki makalelerimde mevcuttur: Kavramlar:

Hangi tür veriler normal değildir? En önemlisi muhtemelen bir referanstır.

Referanslar


Referans bir nesne değildir ve ne düzenli ne de yarı -ortaya çıkmaz:



// referenceIsObject.cpp

#include <funktional>
#include <iostream>
#include <type_traits>

int main() {

std::cout << 'n';

std::cout << std::boolalpha;
std::cout << "std::is_object<int&>::value: "
<< std::is_object<int&>::value << 'n'; // (1)
// 2:
std::cout
<< "std::is_object<std::reference_wrapper<int>>::value: "
<< std::is_object<std::reference_wrapper<int>>::value
<< 'n';

std::cout << 'n';

}



Program çıktısı açıkça özetler. Bir referans (satır 1) bir nesne değildir:









2. satır boyunca programda kim var referenceIsObject.cpp Şaşırmış: Bir Referans int& Bu bir nesne değil, ancak referans sargısı std::reference_wrapper<int> bir nesne. İşte cppReference.com'da bir referans sargısının açıklaması: STD :: REFERANS_WRAPER, kopyalanabilir ve atanabilir bir nesnede bir referansı saran bir sınıf sınıfıdır. Genellikle standart kaplarda referansları saklamak için bir mekanizma olarak kullanılır (normalde referans içeremeyen STD taşıyıcı :: gibi.

Bu, bir referans taşıyıcının std::vector<int&> Bir referans sargısının aksine std::vector<std::reference_wrapper<int>> Geçerli değil. Bu nedenle, C ++ 11'den referans semantiği olan bir konteyner uygulamak mümkündür.



// referenceSemantics.cpp

#include <functional>
#include <iostream>
#include <list>
#include <type_traits>
#include <vector>

int main() {

std::cout << 'n';

std::list<int> myList{1, 2, 3, 4, 5};
std::vector<std::reference_wrapper<int>>
myRefVector(myList.begin(), myList.end());

for (auto l: myList) std::cout << l << " ";
std::cout << "nn";

for (auto& v: myRefVector) v *= v; // (1)

for (auto l: myList) std::cout << l << " "; // (2)

std::cout << "nn";

}


A'nın unsurlarını değiştir std::vector<std::reference_wrapper<int>> (1) Ayrıca referans elemanlarını değiştirin (2).









Normal bir veri türüne ihtiyaç duyan ancak referans kullanan bir algoritmanız varsa C ++ 20 ne olacak?



// needRegularType.cpp

#include <concepts>

template <std::regular T>
class MyClass{};

int main() {

MyClass<int> myClass1;
MyClass<int&> myClass2;

}


Programı mevcut GCC 12.2, mevcut klan 15.0.0 ve mevcut MSVC V19 derleyicisi ile derledim. Microsoft derleyicisi en iyi hata mesajını sağladı:









Sırada ne var?


Değer nesnesi, eşitliği durumuna dayanan, ancak kimliğine dayanmayan küçük bir nesnedir. Nesnelerin bir sonraki makalemin konusu olacağını değerlendirin.


(RME)




Ne yazık ki, bu bağlantı artık geçerli değil.

Boşa harcanan eşyalara olan bağlantılar, 7 günlük daha büyükse veya çok sık çağrılmışsa gerçekleşmez.


Bu makaleyi okumak için bir Haberler+ paketine ihtiyacınız var. Şimdi yükümlülük olmadan bir hafta deneyin – yükümlülük olmadan!
 
Üst