operator<=> implementation is correct?

Hi,

It is not clear to me how to implement the <=> operator. As an example let's look at a type:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
struct Integer
{
	int i;
	long j;

	explicit Integer(int i, long j)
		: i(i), j{j}
	{
	}
	auto operator<=>(const Integer& other) const
	{
		auto ret = i <=> other.i;
		if( ret != std::strong_ordering::equal)
		{
			return ret;
		}
		if( ret == std::strong_ordering::equal)
		{
			auto r2 = j <=> other.j;
			return r2;
		}

	}
};


And it is used like this:

1
2
3
4
5
6
	Integer a(4, 7), b{ 6, 9 };
	auto ret = a <=> b;
	if( a < b)
	{
		int i = 0;
	}


Is operator<=> well defined?

Regards,
Juan
Simplify Your Code With Rocket Science: C++20's Spaceship Operator
https://devblogs.microsoft.com/cppblog/simplify-your-code-with-rocket-science-c20s-spaceship-operator/

There are lots of other examples available on the internet if a bit of effort to hunt for them is done.

https://duckduckgo.com/?t=ffab&q=how+to+use+the+C%2B%2B+spaceship+operator&ia=web
The https://en.cppreference.com/w/cpp/language/default_comparisons explains the defaulted version quiet clearly.

Since your example wants same ordering as the defaulted, you can let the compiler generate the default for you:
1
2
3
4
5
6
struct Integer
{
    int i;
    long j;
    auto operator<=>(const Integer&) const = default;
};



As for your version, we do know that ret == std::strong_ordering::equal is true when ret != std::strong_ordering::equal is false, which makes else more "natural" than a separate if statement.
As you have written, you seem to have:
IF ... THEN return ...
IF ... THEN return ...
end of function

Which makes one ask: "What if both IF are false? There is no return?"

You could write ret != 0. Less typing, but should be equally clear in the context.

Likewise, auto r2 = j <=> other.j; return r2; or return j <=> other.j; ? Style does not make code less or more correct, does it?

Have a look at:
https://www.modernescpp.com/index.php/the-autogenerated-equality-operator/

std::tie() can be used for operator <=>

1
2
3
4
5
6
7
8
9
10
struct Integer {
	int i;
	long j;

	explicit Integer(int i_, long j_) : i(i_), j(j_) {}

	auto operator<=>(const Integer& other) const {
		return std::tie(i, j) <=> std::tie(other.i, other.j);
	}
};



explains the defaulted version quiet clearly


cppreference explaining anything clearly is an oxymoron!
Last edited on
Registered users can post here. Sign in or register to post.