2016-10-27 7 views
1

Я хочу получить объект от set<Node>, но я думаю, что моя функция дает мне копию этого объекта. Как это исправить?Получение объекта из итератора

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

ответ

5

Самый простой способ исправить это сделать ваша функция возвращает ссылку:

Node& findByNum(int n) 

Вы должны убедиться, что узел остается в наборе тех пор, пока вы используете ссылку Это.

+1

Вставка/удаление из 'set' делает недействительными ни итераторы, ни ссылки (cf [здесь] (http://en.cppreference.com/w/cpp/container/set/insert)). Работа с 'set ' (включая интеллектуальные указатели) бессмысленна. – m8mble

+0

@ m8mble: действительно. set > по-прежнему имеет смысл, если вы вообще не хотите, чтобы выполнялось копирование (или если Node не копируется). Ему просто нужен пользовательский компаратор, чтобы он не сравнивал указатели. – Ishamael

+0

Извините, но это неверно. Вы можете создать 'set' из типов, не подлежащих копированию, используя ['set :: emplace'] (http://en.cppreference.com/w/cpp/container/set/emplace). – m8mble

0

Верните iterator вместо значения или ссылки. Вы также можете использовать 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; 
    }); 
} 

Вы можете использовать его как это:

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

Будьте в курсе Iterator invalidation rules.

0

Вы не должны возвращать ссылку, это плохой вариант, если вы не найдете свой объект.
Сохраняя свой исходный код, здесь возможное решение:

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 ответ, кажется, тоже приятно.