How can I find an element in a set which contains

2020-02-29 04:08发布

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.

7条回答
狗以群分
2楼-- · 2020-02-29 04:44

find_foo(new Foo(new Bar("x"))); does not sound like a good idea - it will most likely (in any scenario) lead to memory leak with that search function.

You could use find_if with a functor:

struct comparator {
    Foo* local;
    comparator(Foo* local_): local(local_) {}
    ~comparator() { /* do delete if needed */ } 
    bool operator()(const Foo* other) { /* compare local with other */ }
};

bool found = vec.end() != std::find_if(vec.begin(), vec.end(), comparator(new Foo(...)));
查看更多
登录 后发表回答