0

I would like to create a set containing the objects of my class, I have to determine a custom comparison. Unfortunately, everything I tried did not work.

class My_Class {
    public:
        char letter;
        set<My_Class, compare> Children;
};

Ant then, the compare struct:

struct compare {
    bool operator() (const My_Class& a, const My_Class& b) const{
        return a.letter < b.letter;
    }
};

How can I make this work please?

Currently, the issue displays that identifiers a and b are not declared.

Delgan
  • 18,571
  • 11
  • 90
  • 141
  • Can you expound upon "did not work"? – Fred Larson Jun 26 '14 at 15:12
  • Looks like you may be missing MyClass.h (or whatever) in `compare`'s file. Also, you should probably have `operator()` take `const My_Class&` rather than making a copy. – dlf Jun 26 '14 at 15:18
  • @dlf It is not possible, because both `compare` and `My_Class` are in the same file. I tried to use `My_Class&` but I had the same problem. – Delgan Jun 26 '14 at 15:19
  • Is `compare` above `My_Class`, then? – dlf Jun 26 '14 at 15:19
  • `I would like to create a set containing the objects of my class` Why did you make the `set` a member of My_Class? – PaulMcKenzie Jun 26 '14 at 15:20
  • @Paul Thank you, it seems to solve the issue! – Delgan Jun 26 '14 at 15:22
  • I think that another issue is the usage of an incomplete type (`My_Class`) within itself as you're doing now when you create a `set`. That's why I asked why you're declaring a set of a `My_Class` within `My_Class`. – PaulMcKenzie Jun 26 '14 at 15:37
  • @Paul I read your answer too quickly, I thought you were suggesting me to put `struct compare{}` inside `My_Class{}`, which had the effect to work. To answer you, each object `My_Class` must contain other objects of this type, so I need a set of `My_Class` in `My_Class`, I do not know how I could do anything else. – Delgan Jun 26 '14 at 15:51
  • @user3779937 - That may be so, but I highly suggest you use a different approach such as decoupling that `set` from My_Class. There is no guarantee that the code will compile. Please take a look here: http://www.drdobbs.com/the-standard-librarian-containers-of-inc/184403814. – PaulMcKenzie Jun 26 '14 at 15:57

2 Answers2

2

You are trying to use compare structure inside My_Class, which uses My_Class in its method. It is not a trivial case, but forward declaration will help. So this should work:

class My_Class;

struct compare {
    bool operator() (const My_Class &a, const My_Class &b) const;
};

class My_Class {
public:
    char letter;
    set<My_Class, compare> Children;
};

bool compare::operator() (const My_Class &a, const My_Class &b) const
{
    return a.letter < b.letter;
}

Another alternative would be to pass comparator to std::set constructor, rather than specify it as a template parameter:

class My_Class {
public:
    My_Class();
    char letter;
    set<My_Class> Children;
};

struct compare {
    bool operator() (const My_Class& a, const My_Class& b) const{
        return a.letter < b.letter;
    }
};

My_Class::My_Class() : Children( compare() )
{
}
Slava
  • 43,454
  • 1
  • 47
  • 90
  • See my last comment. I think that the code doesn't even have to compile successfully due to using `set` within the definition of `T`. – PaulMcKenzie Jun 26 '14 at 15:40
0

The problem with your code is that it is not guaranteed to compile. The problem is not the compare struct, so take that out of the picture. It is this:

class My_Class {
public:
    char letter;
    set<My_Class, compare> Children;  // it is the set<My_Class> that is the problem
};

You are defining a std::set of My_Class before the definition of My_Class is known to the compiler. In other words, you're using an incomplete type within the std::set container. There is no guarantee that the code will compile, and even if it did, the behavior now is undefined.

If you want a container that works with incomplete types, you can use the Boost container types here:
http://www.boost.org/doc/libs/1_55_0/doc/html/container.html

Here is the description about Incomplete Types within the Boost documentation: http://www.boost.org/doc/libs/1_55_0/doc/html/container/main_features.html#container.main_features.containers_of_incomplete_types

PaulMcKenzie
  • 34,698
  • 4
  • 24
  • 45