2013-02-28 2 views
5

그래서 내가 벡터과 같이 있습니다원시 포인터가있는 벡터에서 std :: unique_ptr을 삭제하는 가장 좋은 방법은 무엇입니까?

std::vector<std::unique_ptr<SomeClass>> myVector; 

그럼이 SomeClass의 원시 포인터를 포함하는 다른 벡터 :

std::vector<SomeClass*> myOtherVector; 

그것은 또한 myVector 내부에있을 것입니다 myOtherVector 내부 요소가있는 경우, 그래서 나는 myOtherVector에있는 각 요소를 통과하고 myVector에서 같은 요소를 제거하고 싶습니다. 그런 다음 벡터를 지 웁니다.

for(size_t i = 0; i < myOtherVector.size(); i++) 
{ 
    myVector.erase(std::remove(myVector.begin(), myVector.end(), myOtherVector[i]), myVector.end()); 
} 
myOtherVector.clear(); 

myVector 고유 포인터를 보유하지만 난 remove() 기능을 원시 포인터를주는거야 때문에 이것은 컴파일시 오류가 발생합니다 : 이것은 내가 생각 해낸 것입니다. 이것은 내가이 문제를 해결할 적절한 방법이 무엇인지 모르기 때문에 도움이 필요한 곳입니다. 이 모든

myVector.erase(std::remove(myVector.begin(), myVector.end(), std::unique_ptr<SomeClass>(myOtherVector[i])), myVector.end()); 

프리스트 지금은 같은 객체를 참조하는 두 std::unique_ptr들 때문에 잘못된 : 나는에 라인을 변경했습니다. myVector 내부의 요소에는 참조가 포함되어 있으며 위의 행에서 고유 한 포인터의 구성이 또 다른 참조입니다. 그리고 같은 유형을 얻기 위해 새 포인터를 생성하는 것이 개념적으로 올바른 작업을 수행하는 것인지 알지 못합니다. 그럼 내가 공유 포인터에 고유 포인터를 변경 : ". ApplicationName.exe가 중단 점을 트리거하고있다"나는 myVector.erase() 라인 말했다 런타임 오류가 발생하여 응용 프로그램을 실행

std::vector<std::shared_ptr<SomeClass>> myVector; 
std::vector<SomeClass*> myOtherVector; 

for(size_t i = 0; i < myOtherVector.size(); i++) 
{ 
    myVector.erase(std::remove(myVector.begin(), myVector.end(), std::shared_ptr<SomeClass>(myOtherVector[i])), myVector.end()); 
} 
myOtherVector.clear(); 

계속 클릭하면 디버그 어설 션 오류가 발생합니다.

분명히 내가 잘못하고있는 것이 분명하지만, 나는 무엇을 모르겠다. 원시 포인터가있는 벡터에서 스마트 포인터를 지우는 올바른 방법은 무엇입니까?

+0

당신이 생각 했 unique_ptr에서)를가 (얻을 기능을 비교 원시 포인터를 지정해야합니다? –

+0

'std :: unique_ptr'는 소유 포인터를 반환하는'get' 멤버를 가지고 있습니다. –

+1

어, 제안입니다. 'std :: shared_ptr'라고하는 또 다른 C++ 11 스마트 포인터가 있습니다. –

답변

1

이것은 내가 어떻게 할 것입니다. 성능은 향상 될 수 있지만 응용 프로그램의 병목 지점이되지 않는 한 그 내용을 신경 쓸 필요가 없습니다. 알고리즘은 간단하고 명확합니다.

remove_if을 사용하여 두 번째 컨테이너 (myOtherVector)의 요소가 가리키는 개체를 가리키는 모든 요소를 ​​첫 번째 컨테이너 (myVector)에서 선택적으로 제거합니다. 그런 다음 두 번째 컨테이너를 지 웁니다. ,

#include <vector> 
#include <memory> 
#include <algorithm> 

struct SomeClass { /* ... */ }; 

int main() 
{ 
    std::vector<std::unique_ptr<SomeClass>> myVector; 
    std::vector<SomeClass*> myOtherVector; 

    myVector.erase(
     std::remove_if(// Selectively remove elements in the second vector... 
      myVector.begin(), 
      myVector.end(), 
      [&] (std::unique_ptr<SomeClass> const& p) 
      { // This predicate checks whether the element is contained 
       // in the second vector of pointers to be removed... 
       return std::find(
        myOtherVector.cbegin(), 
        myOtherVector.cend(), 
        p.get() 
        ) != myOtherVector.end(); 
      }), 
     myVector.end() 
     ); 

    myOtherVector.clear(); 
} 
3

std::unique_ptr에는 소유 포인터를 반환하는 멤버 함수 get이 있습니다.

는 다음과 같은 고려 :

std::sort(myOtherVector.begin(), myOtherVector.end()); 

myVector.erase(std::remove_if(myVector.begin(), myVector.end(), 
[&](std::unique_ptr<SomeClass> const& p) -> bool 
{ 
    return std::binary_search(myOtherVector.begin(), myOtherVector.end(), 
           p.get()); 
})); 

myOtherVector.clear();  
0

당신이 당신의 문제를 단순화하지 못할 경우 어떻게 표준 : set_difference 또는 그 친족 (http://www.cplusplus.com/reference/algorithm/set_difference/) 중 하나에 대한 : 술어는 람다 함수를 통해 구현된다?

당신은 시작 원시 포인터의 벡터를 유지하지 않음으로써 누가 문제를 단순화

관련 문제