Reputation: 357
I have a typedef struct defined like so:
typedef struct myStruct {
int id;
double value;
bool operator <(const myStruct &x, const myStruct &y) {
return (x.id < y.id);
}
} myStruct;
I need to use this struct as a key in a std::map, thus the overloaded operator. However, I get the following error message when trying to compile this:
overloaded 'operator<' must be a binary operator (has 3 parameters)
Okay, so I tried this instead:
bool operator <(const pointcloud_keyframe &x) {
return (this->id < x.id);
}
However, that doesn't work either as I get this error message when trying to insert into the map:
invalid operands to binary expression ('const myStruct' and 'const myStruct')
Please help!
Upvotes: 0
Views: 1275
Reputation: 10875
Given the code you've shown, you're pretty close, but not quite there ... you need to distinguish between a member function and a stand-alone "free" function.
struct myStruct final { int id; };
inline bool operator<(const myStruct& lhs, const myStruct& rhs) {
return lhs.id < rhs.id;
}
Keep in mind that you should prefer to use non-member functions.
Using a member function is similar, but less desirable than above:
class myStruct final
{
int id_;
public:
bool operator<(const myStruct& rhs) const {
return id_ < rhs.id_;
}
};
Another way would be to make operator<()
a friend
function, which has various tradeoffs; but your original code doesn't show that technique.
Upvotes: 3
Reputation: 275820
struct myStruct {
int id;
double value;
friend bool operator <(const myStruct &x, const myStruct &y) {
return (x.id < y.id);
}
};
the key part is friend
. I also removed the typedef
; in C++ struct myStruct
already defines a type named myStruct
, no need to also typedef
it.
There are other ways to make your code compile, but this is the easiest.
Without friend
, your operator<
is a member function, and member operator<
takes one argument plus an implicit this
.1
With friend
, it becomes a "free function" that takes 2 arguments. I find this is the cleanest way to do it. It still has full permission to access private bits of your struct
(which it may not need).
You could also move it outside of the struct
itself
struct myStruct {
int id;
double value;
};
inline bool operator <(const myStruct &x, const myStruct &y) {
return (x.id < y.id);
}
but <
being a friend
is relatively harmless. In addition, with template
types, the friend strategy scales better. So I'd get used to using it, even if technically "less permissions is better".
1 I find this annoyingly asymmetrical, so I prefer non-member <
to member <
.
Upvotes: 5