0

I have a struct and would like to implement a set of its pointers. So I try to overload operator < to make it happen. One limitation here is that I do not have access to write overloading code within the struct definition. How can I do it outside of the struct?

Here is what I have so far:

#include<iostream>
#include<set>
#include<vector>

using namespace std;

struct mystruct {
    int label;
    vector<mystruct *> neighbors;
};
bool operator < (mystruct * n1, mystruct* n2) {
    return n1 -> label < n2 -> label;
};
int main() {
    set<mystruct *> s;
    return 0;
}

The error message is

error: overloaded 'operator<' must have at least one parameter of class or enumeration type

Yi Bao
  • 165
  • 2
  • 15

1 Answers1

3

The problem with

bool operator < (mystruct * n1, mystruct* n2) {
    return n1 -> label < n2 -> label;
};

Is that both n1 and n2 are pointers. Even though they are pointers to mystruct they are still just pointers and you cannot overload operators for pointers as they are built in. The simplest way to fix this is to take references instead and work with values like

bool operator < (const mystruct& n1, const mystruct7 n2) {
    return n.label < n2.label;
};

int main() {
    set<mystruct> s;
    return 0;
}

If you can't do that then you need to provide a comparison functor to the std::set and have it use that function instead of operator <. That would look like

struct mystruct_pointer_comp
{
    bool operator ()(mystruct * n1, mystruct* n2) {
        return n1->label < n2->label;
    };
}

int main() {
    set<mystruct *, mystruct_pointer_comp> s;
    return 0;
}
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • An intermediate solution (if you don't want to give ownership of the objects to the container) could be to create the "regular" overload with references, and use a `std::set>`. – Matteo Italia May 25 '17 at 16:34
  • @MatteoItalia Not sure how well that would work since the objects the wrapper wraps will need to exist outside the set and for as long as the set exists. – NathanOliver May 25 '17 at 16:36
  • @MatteoItalia Most probably more something like a `std::set>` then. But it's questionable why to use a `std::set` then at all. – πάντα ῥεῖ May 25 '17 at 16:41