跳至內容

C++/compare

維基教科書,自由的教學讀本
< C++

飛船運算符(spaceship operator)<=>在C++20中叫做三向比較(three way comparation),它提出了一些新的概念,包括強有序、弱有序、強相等、弱相等(strong ordering/weak ordering/strong equality/weak equality)。

全部可能的返回值類型和其enum對應的值
-1 0 +1 非數的值 注釋
std::strong_ordering less equal greater 全序、可替代
std::weak_ordering less equivalent greater 全序、不可替代(即有一些成員不參與比較、可能是不同的)
std::partial_ordering less equivalent greater unordered 偏序、不可替代(即有一些成員不參與比較、可能是不同的)
std::strong_equality equal nonequal 全序、可替代
std::weak_equality equivalent nonequivalent 不可替代(即有一些成員不參與比較、可能是不同的)

類成員中有容器類型(例如vector)時,需要將operator==單獨列出來。因為編譯器生成的operator==的代碼,對於容器類型會先比較容器的size,如果size不同,則必定不等,size相等再去逐個比較內容,這樣實現效率高,但是operator<=>要同時實現幾個運算符的邏輯,它生成的代碼是從頭比到尾,對於容器也是如此,並不會先去比size,所以在有容器成員的時候它生成的operator==代碼性能不是最高 例子1:

#include <iostream>     // std::cout
#include <tuple>        // std::tuple, std::make_tuple, std::tie
#include <string>
#include <compare>
using namespace std;
struct Name {
	string first_name;
	string mid_name;
	string last_name;

//实现了三值的operator<,同时还实现了==, !=, >, >=, <= 运算符:
	std::strong_ordering operator<=>(const Name&) const = default;

};

int main()
{
	Name a{ "hello", "world", "Lee" };
	Name b{ "hello", "world1", "Lee" };
	std::cout << (a <= b) <<std::endl;
	std::strong_ordering v = (a <=> b);
	std::cout << int(v._Value);
	return 0;
}


例子2:

#include <iostream>     // std::cout
#include <tuple>        // std::tuple, std::make_tuple, std::tie
#include <string>
#include <compare>
using namespace std;
struct ID {
    int id_number;
    auto operator<=>(const ID&) const = default;
};

struct Person {
    ID id;
    string name;
    string email;
    std::weak_ordering operator<=>(const Person& other) const
    {
        return id <=> other.id;
    }
};


int main()
{
    Person a{ 3, "world", "Lee" };
    Person b{ 2, "world1", "Lee" };
	auto v = (a <=> b);
	std::cout << int(v._Value);
	return 0;
}