C ++ Programlama Dili: Otomatik Oluşturulan Eşitlik Operatörü

Adanali

Active member
C ++ Programlama Dili: Otomatik Oluşturulan Eşitlik Operatörü


  1. C ++ Programlama Dili: Otomatik Oluşturulan Eşitlik Operatörü

Çoğu C ++ geliştiricisi, üç yollu karşılaştırma operatörünün tanımlaması veya =default Derleyici tarafından talep edilebilir. Muhtemelen eşitlik operatörünün C ++ 20'de de tanımlanabileceği veya talep edilebileceği daha az biliniyor mu?











Otomatik olarak oluşturulan eşitlik operatörüne girmeden önce, üç yollu karşılaştırma operatöründeki en önemli gerçekleri güncellemek istiyorum.








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.







Üç yollu karşılaştırma operatörü


Üç yollu karşılaştırma operatörü tanımlanabilir veya =default Derleyici tarafından talep edildi. Her iki durumda da altı karşılaştırma operatörünü de alırsınız: ==, !=, <, <=, >, VE >=.



// threeWayComparison.cpp&#13;
&#13;
#include <compare>&#13;
#include <iostream>&#13;
&#13;
struct MyInt {&#13;
int value;&#13;
explicit MyInt(int val): value{val} { }&#13;
auto operator<=>(const MyInt& rhs) const { // (1) &#13;
return value <=> rhs.value;&#13;
}&#13;
};&#13;
&#13;
struct MyDouble {&#13;
double value;&#13;
explicit constexpr MyDouble(double val): value{val} { }&#13;
auto operator<=>(const MyDouble&) const = default; // (2)&#13;
};&#13;
&#13;
template <typename T>&#13;
constexpr bool isLessThan(const T& lhs, const T& rhs) {&#13;
return lhs < rhs;&#13;
}&#13;
&#13;
int main() {&#13;
&#13;
std::cout << std::boolalpha << std::endl;&#13;
&#13;
MyInt myInt1(2011);&#13;
MyInt myInt2(2014);&#13;
&#13;
std::cout << "isLessThan(myInt1, myInt2): "&#13;
<< isLessThan(myInt1, myInt2) << std::endl;&#13;
&#13;
MyDouble myDouble1(2011);&#13;
MyDouble myDouble2(2014);&#13;
&#13;
std::cout << "isLessThan(myDouble1, myDouble2): "&#13;
<< isLessThan(myDouble1, myDouble2) << std::endl; &#13;
&#13;
std::cout << std::endl;&#13;
&#13;
}


Beklendiği gibi derleyicinin çalışması tarafından üretilen üç yollu karşılaştırma operatörü (1) ve (2) (2).











Bununla birlikte, iki üç yollu karşılaştırma operatörü arasında bazı dikkate değer farklılıklar vardır. İçin geri dönüş türü MyInt (1) titiz siparişi, geri dönüş türünü destekler MyDouble (2) Öte yandan, sadece kısmi düzeni destekler. Sleit üreten sayılar sadece kısmi sırayı destekleyebilir, çünkü NAN gibi değerler sipariş edilemez (bir sayı değil). Örneğin, bu NaN == NaN İLE false değerlendirildi.

Derleyici tarafından oluşturulan üç yollu karşılaştırma operatörü, örtük constexpr VE noexcept Başlık gerekli <compare>. Ayrıca sözlükbilimsel bir karşılaştırma gerçekleştirir. Bu bağlamda, sözlükbilimsel karşılaştırma, tüm temel sınıfların sağa ve tüm statik olmayan üyelerin beyanlarına göre karşılaştırıldığı anlamına gelir.

Diyelim ki iki sınıfı ekliyorum MyInt VE MyDouble A std::unordered_set Üstelik.



struct MyInt {&#13;
int value;&#13;
std::unordered_set<int> mySet;&#13;
explicit MyInt(int val): value{val}, mySet{val} { }&#13;
bool operator<=>(const MyInt& rhs) const {&#13;
if (auto first = value <=> rhs.value; first != 0) return first;&#13;
else return mySet <=> rhs.mySet; &#13;
}&#13;
};&#13;
&#13;
struct MyDouble {&#13;
double value;&#13;
std::unordered_set<double> mySet;&#13;
explicit MyDouble(double val): value{val}, mySet{val} { }&#13;
bool operator<=>(const MyDouble&) const = default; &#13;
};&#13;



Üç yollu karşılaştırmayı talep edin veya tanımlayın çünkü std::unordered_set Sipariş desteklenmez. std::unordered_set Yalnızca karşılaştırmaları destekler ve bu da geçerlidir MyInt VE MyDouble.

Eşitlik Operatörü


Eşitlik operatörü tanımlanır veya derleyici ile =default İstenen, eşitlik ve eşitsizlik operatörlerini otomatik olarak alır: ==VE !=.



// equalityOperator.cpp&#13;
&#13;
#include <iostream>&#13;
#include <tuple>&#13;
#include <unordered_set>&#13;
&#13;
struct MyInt {&#13;
int value;&#13;
std::unordered_set<int> mySet;&#13;
explicit MyInt(int val): value{val}, mySet{val} { }&#13;
bool operator==(const MyInt& rhs) const { &#13;
return std::tie(value, mySet) == std::tie(rhs.value, rhs.mySet);&#13;
}&#13;
};&#13;
&#13;
struct MyDouble {&#13;
double value;&#13;
std::unordered_set<double> mySet;&#13;
explicit MyDouble(double val): value{val}, mySet{val} { }&#13;
bool operator==(const MyDouble&) const = default; &#13;
};&#13;
&#13;
template <typename T>&#13;
constexpr bool areEqual(const T& lhs, const T& rhs) {&#13;
&#13;
return lhs == rhs;&#13;
}&#13;
&#13;
template <typename T>&#13;
constexpr bool areNotEqual(const T& lhs, const T& rhs) {&#13;
&#13;
return lhs != rhs;&#13;
}&#13;
&#13;
int main() {&#13;
&#13;
std::cout << std::boolalpha << 'n';&#13;
&#13;
MyInt myInt1(2011);&#13;
MyInt myInt2(2014);&#13;
&#13;
std::cout << "areEqual(myInt1, myInt2): "&#13;
<< areEqual(myInt1, myInt2) << 'n';&#13;
std::cout << "areNotEqual(myInt1, myInt2): "&#13;
<< areNotEqual(myInt1, myInt2) << 'n';&#13;
&#13;
std::cout << 'n'; &#13;
&#13;
MyDouble myDouble1(2011.0);&#13;
MyDouble myDouble2(2014.0);&#13;
&#13;
std::cout << "areEqual(myDouble1, myDouble2): "&#13;
<< areEqual(myDouble1, myDouble2) << 'n';&#13;
std::cout << "areNotEqual(myDouble1, myDouble2): "&#13;
<< areNotEqual(myDouble1, myDouble2) << 'n'; &#13;
&#13;
std::cout << 'n';&#13;
&#13;
}


Şimdi yapabilirim MyInt VE MyDouble Eşitlik ve eşitsizlik ile karşılaştırın.

Programda equalityOperator.cpp Bir hile uyguladım: Onu kim tanıyor?

Aşağıdaki örnekte eşitlik operatörü var MyInt Eşitlik operatörleri tarafından uygulandı value VE mySet Zincirlendiler.



struct MyInt {&#13;
int value;&#13;
std::unordered_set<int> mySet;&#13;
explicit MyInt(int val): value{val}, mySet{val} { }&#13;
bool operator==(const MyInt& rhs) const {&#13;
if (auto first = value == rhs.value; first != 0) return first;&#13;
else return mySet == rhs.mySet; &#13;
}&#13;
};


Bu, hatalara oldukça eğilimlidir ve birkaç üyeyle bir dersiniz olduğunda tatsız görünüyor.

Aksine var std::tie Programdaki eşitlik operatörüne alışkın equalityOperator.cpp Uygulamak için.



struct MyInt {&#13;
int value;&#13;
std::unordered_set<int> mySet;&#13;
explicit MyInt(int val): value{val}, mySet{val} { }&#13;
bool operator==(const MyInt& rhs) const { &#13;
return std::tie(value, mySet) == std::tie(rhs.value, rhs.mySet);&#13;
}&#13;
};&#13;



std::tie Bir torpella yaratmak lvalue-argümanlarına katılıyor. Son olarak, üretilen tupiler sözlükbilimsel olarak karşılaştırılır.

Sırada ne var?


Bir sonraki makalemde, C ++ 20 üzerinden yolculuğuma devam edeceğim std::span yazmak. std::span Nesnelerin tutarlı bir bölümünü ifade eden bir nesneyi temsil eder.


(harita)
 
Üst