2011-08-04 2 views
0

아래의 코드에서 항목을 찾으면 for_each에 알리고 싶습니다. 어떻게 그럴 수 있죠?이 경우 for_each에 true 또는 false를 반환하는 방법은 무엇입니까?

#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; 
} 

답변

6

해결책은 다음과 같습니다. 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를 사용하는 경우,가 필요하지 않습니다.functor입니다. 결국 주소 (예 : 포인터) 만 비교하는 것입니다.

그런데 목록에 개의 고유 한 요소가 포함되어 있고 중복을 원하지 않는 것처럼 보입니다. 그 그렇다면, 당신은 더 나은 고려 : std::set

std::set

  • 자동으로 dupilcate 요소를 처리합니다. 즉,이 작업을 수행 할 수는 없습니다 그것에 경우
    m_widgetSet.insert(pi); 
    

    후가 세트로 pi를 삽입합니다. 이미 포함되어있는 경우 insert은 세트에 삽입하지 않습니다.

+1

'std :: set'에 +1 (C++ 0x에서도'std :: unordered_set'을 고려할 것입니다. 왜냐하면 주문은 가져 오지 않는 것 같기 때문입니다). 데이터 구조의 적절한 선택은 근본적이며,'std :: list'의 사용은 대개 의심 스럽습니다 (단순히 사람들이 목록을 알고있는 것처럼 보이기 때문에 ...). –

관련 문제