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;
}