Как вернуть true или false в for_each в этом случае? - PullRequest
0 голосов
/ 04 августа 2011

В моем коде ниже я хочу сообщить for_each, если я найду предмет? Как это сделать?

#include <list>
#include <algorithm>
#include <functional>

using namespace std;

class widget {
 public:
  widget(int id) : m_id(id) {}

private:
   int m_id;
};

class findwidget {
public:
   findwidget(widget* p) : m_widget(p) {}

   bool operator()(widget* p) const { 
      return p == m_widget ? true : false;
   }

   widget* m_widget;
};

list<widget*> m_widgetList;

void push_back(widget* pi){
   if(m_widgetList.empty()) {
      m_widgetList.push_back(pi);
   } else {
      if(!std::for_each(m_widgetList.begin(), m_widgetList.end(), findwidget(pi)))
         m_widgetList.push_back(pi);
   }
}

int main(int argc, char* argv[])
{
   widget w1(1);
   push_back(&w1);
   return 0;
}

1 Ответ

6 голосов
/ 04 августа 2011

Решение: не используйте std::for_each. Используйте любое из следующего (что подходит для вашей ситуации):

Пример std::find:

if(std::find(m_widgetList.begin(), m_widgetList.end(),pi) == m_widgetList.end())
     m_widgetList.push_back(pi);

Обратите внимание: если вы используете std::find, вам не нужен функтор findWidget. В конце концов, вы сравниваете только адреса (то есть указатели).

Кстати, кажется, вы хотите, чтобы список содержал уникальных элементов, и не хотели бы хранить дубликаты. Если это так, то вам лучше подумать:

std::set автоматически обработает дубликаты элементов. То есть вы можете сделать это:

m_widgetSet.insert(pi);

тогда он вставит pi в набор, если его нет в нем. И если он уже содержит его, insert не вставит его в набор.

...