2009-09-07 6 views
3

STL 컨테이너가 있다면 아래의 exmple처럼 포인터 목록을 제거 할 수 있습니다. weak_ptrs의 컨테이너에서는 비교할 수 없기 때문에 이것이 작동하지 않습니다. 먼저 잠글 필요가 있기 때문입니다. 내가 무엇을 할 수 있을지?std :: tr1 :: weak_ptr이있는 컨테이너에서 std :: remove를 어떻게 사용할 수 있습니까?

void MyClass::RemoveItem(std::tr1::weak_ptr<Item> const & pItem) 
{ 
    mylist.remove(pItem); 
} 
+2

약 포인터가 가리키고 있기 때문에 잠글 수없는 경우 어떻게됩니까? – Omnifarious

+0

sbk의 대답을 사용하여 p.lock()은 p에 shared_ptr을 반환합니다. p는 thisItem.lock()과 일치하지 않으므로 여전히 작동합니다. p.lock()은 결코 throw되지 않습니다. –

답변

5

포함하는 것을 잊지, 당신은 어떤 weak_ptr를 위해 운영자 ==를 정의 할 수 있습니다. 이것이 구현되지 않은 이유가있을 것이라고 확신합니다. 아마도 나중에 추측 할 수 있습니다.

template <typename T> 
bool operator == (const std::tr1::weak_ptr<T>& a, const std::tr1::weak_ptr<T>& b) 
{ 
    return a.lock() == b.lock(); 
} 

... 평소처럼 remove()를 호출 할 수 있습니다. 이건 좀 극단적 인 것 같아.

struct EqPredicate 
{ 
    const boost::weak_ptr<Item>& theItem; 

    EqPredicate(const boost::weak_ptr<Item>& item) : theItem(item) 
    { 
    } 

    bool operator() (const boost::weak_ptr<Item>& p) const 
    { 
     return p.lock() == theItem.lock(); 
    } 
}; 

다음과 같이 사용 :

mylist.remove_if(EqPredicate(pItem)); 

그것을

당신이 remove_if() 접근 방식을 고수하는 경우, 당신은 함수 객체를 사용하여 바인드 마법 *의 제거 얻을 수 더 많은 코드처럼 보이지만 EqPredicate 클래스를 압축 할 수 있습니다. 또한 Item 이외의 유형을 포함하는 목록과 함께 사용하기 위해 템플릿을 만들 수 있습니다.

아, 비교 기능을 포함하여 어디서나 weak_ptrs를 참조로 전달해야합니다.

* 바인드는 성능면에서 무료가 아닙니다. 많은 Remove() 호출을 기대하고 성능을 많이 신경 쓰면 성능을 피하는 것이 좋습니다.

0

답변을 찾기 위해 영원히 검색했기 때문에.

weak_ptrs를 비교하고 하나의 인수를 바인드하는 함수를 만듭니다.

bool weak_ptr_comparsion(Item::wPtr a, Item::wPtr b) 
    { 
     return a.lock() == b.lock(); 
    } 

    void MyClass::RemoveItem(Item::wPtr const & pItem) 
    { 
     mylist.remove_if(std::tr1::bind(weak_ptr_comparsion, pItem, 
         std::tr1::placeholders::_1)); 
    } 

그나마 한 가지를 들어 <tr1/functional>

+1

함수 객체를 대신 사용하고 참조로 매개 변수를 가져야하는 것처럼 보입니다. – rlbond

0

나는 sbk의 접근법에 관한 문제가 weak_ptr 연산자 ==가 경쟁을위한 잠재력이 있다고 생각한다. 연산자 ==에서 돌아와도 a 또는 b에 대한 shared_ptr을 보장 할 수 없으므로 결과 코드를 잘못 해석 할 수 있습니다. 그와

, 당신이 할 수있는 최선 인 것 같다 : 그 유용하지 않습니다

if(a == b) { 
    boost::shared_ptr<Item> a_locked(a.lock()); 
    boost::shared_ptr<Item> b_locked(b.lock()); 
    // It is an error to assume a_locked == b_locked here 
    // It is an error to assume a.lock() == b.lock() here 
    // It is an error to assume a.get() or b.get() here 
} 

합니다. 이제 컨테이너를 반복하면서이 시점에서 반복기를 제거 할 수는 있지만, 잘못된 비교를 약간만하면되는 경우가 더 많습니다.

관련 문제