Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I find an element in a set which contains pointers to the elements?

Edit: I fixed my mistake: I'm using a set and not a vector.

Please consider the following example code:

set<Foo *> set_of_foos;

set_of_foos.insert(new Foo(new Bar("x")));
set_of_foos.insert(new Foo(new Bar("y")));
[...]

// The way a "foo" is found is not important for the example.
bool find_foo(Foo *foo) {
  return set_of_foos.end() != set_of_foos.find(foo);
}

Now when I call:

find_foo(new Foo(new Bar("x")));

the function returns false since what I'm looking for can't be found. The reason is obvious to me: The pointers point to different objects since they are allocated both with a new, resulting in different values of the addresses.

But I want to compare the contents of Foo (i.e. "x" in the above example) and not Foo * itself. Using Boost is not an option as well as modifying Foo.

Do I need to loop through each of the Foo * inside set_of_foos or is there a simpler solution? I tried uniquely serializing the contents of each Foo and replace the set<Foo *> with a map<string, Foo *>, but this seems like a very "hacked" solution and not very efficient.

like image 480
DrColossos Avatar asked Dec 22 '22 21:12

DrColossos


1 Answers

Change your vector to set with your custom comparable function to compare Foo objects.

Should be:

struct ltFoo
{
  bool operator()(Foo* f, Foo* s) const
  {
    return f->value() < s->value();
  }
};

set<Foo*, ltFoo> sFoo;
sFoo.insert(new Foo(new Bar("x"));
sFoo.insert(new Foo(new Bar("y"));

if (sFoo.find(new Foo(new Bar("y")) != sFoo.end())
{
    //exists
}
else
{
    //not exists
}
like image 115
Svisstack Avatar answered Dec 24 '22 10:12

Svisstack