user1765354
user1765354

Reputation: 357

C++ Unable to overload < operator in typedef struct

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

Answers (2)

&#208;аn
&#208;аn

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

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

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

Related Questions