Consider the following:
#include <iostream>
#include <set>
struct foo {
foo (int i) : i {i} {}
auto operator<=> (const foo& other) const {
std::cout << "Call (" << i << "," << other.i << ")" << std::endl;
return i <=> other.i;
}
int i = 0;
};
int main () {
auto m = std::set <foo> ();
m.insert (3);
std::cout << "Inserting 8" << std::endl;
m.insert (8);
std::cout << "Checking 3" << std::endl;
m.contains (3);
std::cout << "Checking 8" << std::endl;
m.contains (8);
std::cout << "Checking 5" << std::endl;
m.contains (5);
}
This outputs:
Inserting 8
Call (8,3)
Call (3,8)
Call (8,3)
Checking 3
Call (3,3)
Call (3,3)
Checking 8
Call (3,8)
Call (8,8)
Call (8,8)
Checking 5
Call (3,5)
Call (8,5)
Call (5,8)
I would have expected that operator<=> would be called once for the first insertion, maybe twice, but three times seems very much wasteful. Similarly, all the comparisons to search for elements check for both (x, y) and (y, x), not leveraging operator<=>.
Question: Why isn't std::set using the full power of operator<=> ?