1

I want to get object from set<Node> but I think my function gives me copy of this object. How to fix it?

Node findByNum(int n){
    for (set<Node>::iterator it = this->children.begin();it != this->children.end(); it++){
        if ((*it).num == n){
            return (*it);
        }
    }
}
Humam Helfawi
  • 19,566
  • 15
  • 85
  • 160
byqqu
  • 21
  • 3

3 Answers3

5

The easiest way to fix it is to make your function return a reference:

Node& findByNum(int n)

You need to make sure that the node stays in the set for as long as you use a reference to it.

Ishamael
  • 12,583
  • 4
  • 34
  • 52
  • 1
    Inserting / deleting from `set` invalidates neither iterators nor references (cf [here](http://en.cppreference.com/w/cpp/container/set/insert)). Working with `set` (including smart pointers) is pointless. – m8mble Oct 27 '16 at 07:50
  • @m8mble: indeed. set> is still meaningful if you don't want copying to occur at all (or if Node is not copyable). It just needs a custom comparator so that it doesn't compare pointers. – Ishamael Oct 27 '16 at 18:50
  • Sorry, but this is not correct either. You can build `set`s of non-copyable types using [`set::emplace`](http://en.cppreference.com/w/cpp/container/set/emplace). – m8mble Oct 27 '16 at 18:56
  • @m8mble: indeed again :) – Ishamael Oct 27 '16 at 19:00
0

Return an iterator instead of value or reference. You may also use std::find_if:

set<Node>::iterator Node findByNum(const int n){
    return std::find_if(children.begin(),children.end(),[n](const Node& item){
        return item.num==n;
    });
}

You may use it like this:

auto it_5=findByNum(5);
std::cout << it_5->n;

Be aware of Iterator invalidation rules.

Community
  • 1
  • 1
Humam Helfawi
  • 19,566
  • 15
  • 85
  • 160
0

You shouldn't return a reference, it's a bad option if you don't find your object.
Keeping your original code, here is a possible solution:

set<Node>::iterator findByNum(int n)
{
    for (set<Node>::iterator it = this->children.begin(); it != this->children.end(); ++it)
    {
        if ((*it).num == n)
            return it;
    }
    return this->children.end();
}

@Human answer seems also nice.

Carl
  • 139
  • 7