19 Kasım 2020 Perşembe

Three-way comparison operator (spaceship operator) - C++20 ile geliyor

Giriş
Şu satırı dahil ederiz.
#include <compare>
Bu operator C++20 ile geliyor ve bir sürü operator yazmaktan yerine tek bir spaceship operator yazılmasına imkan vererek kodu basitleştiriyor. Aslında bu operator Java'daki compareTo ile aynı

Sonuç Olarak Ne Döner
Açıklaması şöyle. Yani bu operator bir  object döner. Bunlar std::weak_ordering, std::partial_ordering, std::strong_ordering olabilir. Eğer bunları metod imzasına yazmak istemiyorsak, auto da dönebiliriz.
The expression a <=> b returns an object that compares <0 if a < b, compares >0 if a > b, and compares ==0 if a and b are equal/equivalent.
1. std::strong_ordering Sonucu
Eğer sonuç olarak std::strong_ordering kullanıyorsak şu değerleri alabilir.
1. std::strong_ordering::less
2. std::strong_ordering::equivalent
3. std::strong_ordering::equal
4. std::strong_ordering::greater
1.1 equivalent vs equal ise
Açıklaması şöyle. Yani std::strong_ordering açısında her ikisi de aynı, her iki parametre equals ise birbirlerinin yerine geçebilirler. Equality implies substitutability. Ancak diğer sonuç tiplerinde equivalence kullanmak gerekir.
They are the same thing, both numerically and conceptually. If a comparison generates strong ordering between the items being compared, equivalence and equality are the same.

The reason there are two words for it is because this is not the same for other kinds of ordering. Weak and partial don't have equality at all; they only provide equivalence.

Equivalence means that two objects can compare equal. Equality implies something stronger; if they compare equal, one can be substituted for the other in any const usage:
Örnek
Elimizde şöyle bir kod olsun. Çıktı olarak "Equivalent ve Equal" alırız
#include <iostream>
#include <compare>
int main()
{
  std::strong_ordering res = (2<=>2);
  if(res == std::strong_ordering::equivalent)
  {
    std::cout<<"Equivalent...."<<std::endl;
  }
  if(res == std::strong_ordering::equal)
  {
    std::cout<<"Equal"<<std::endl;
  }
  return 0;
}
1.2 less ise
Açıklaması şöyle
The <=> is a three-way comparison which implies that you get not just a binary result, but an ordering (in most cases) and if you have an ordering you can express that ordering in terms of any relational operations. 

A quick example, the expression 4 <=> 5 in C++20 will give you back the result std::strong_ordering::less. The std::strong_ordering::less result implies that 4 is not only different from 5 but it is strictly less than that value, this makes applying the operation (4 <=> 5) < 0 correct and exactly accurate to describe our result.
2. std::partial_ordering Sonucu

Örnek
Her bir üyenin teker teker karşılaştırılması için şöyle yaparız. Şöyle yaparız. Burada metod imzasında auto kullanılıyor
auto X::operator<=>(const Y&) =default;
Örnek - std::partial_ordering
Şöylee yaparız
std::partial_ordering operator <=>(const QVariant& l, const QVariant& r) {
    return l.type() == QMetaType:Int? l.toInt() <=> r.toInt()
         : l.type() == QMetaType::Double? l.toDouble() <=> r.toDouble()
         : throw;
}
Örnek - std::partial_ordering
Şöyle yaparız.
class PersonInFamilyTree { // ...
public:
  std::partial_ordering operator<=>(const PersonInFamilyTree& that) const {
    if (this->is_the_same_person_as ( that)) return partial_ordering::equivalent;
    if (this->is_transitive_child_of( that)) return partial_ordering::less;
    if (that. is_transitive_child_of(*this)) return partial_ordering::greater;
    return partial_ordering::unordered;
  }
  // ... other functions, but no other comparisons ...
};
3. std::weak_ordering Sonucu
Açıklaması şöyle
a total ordering, where equality actually only defines an equivalence class. The canonical example here is case-insensitive string comparison – where two objects might be weak_ordering::equivalent but not actually equal (hence the naming change to equivalent).

Hiç yorum yok:

Yorum Gönder