2013-02-28 84 views
5

所以我有一個載體,像這樣:使用原始指針從矢量中刪除std :: unique_ptr的最佳方法?

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

然後,我有其中包含的SomeClass原始指針的另一種載體:

std::vector<SomeClass*> myOtherVector; 

如果裏面有myOtherVector的元素也將是內部myVector,所以我想通過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中的元素包含一個引用,上面一行中唯一指針的構造是另一個引用。我甚至不知道構建一個新指針來獲取相同類型在概念上是正確的做法。於是我改變了獨特的指針共享指針:

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(); 

當我跑了myVector.erase()線導致,其中所述運行時錯誤的應用程序「ApplicationName.exe引發了斷點。」在點擊繼續時我得到了一個調試斷言失敗。

所以顯然我做錯了什麼,但我不知道是什麼。使用原始指針從矢量中刪除智能指針的正確方法是什麼?

+0

你有沒有考慮簡化了誰的只是不保持原始指針的矢量開始與問題,指定一個比較函數來獲取()原始指針? – 2013-02-28 01:07:00

+0

'std :: unique_ptr'有一個返回擁有指針的'get'成員。 – 2013-02-28 01:07:13

+1

呃,一個建議。還有另外一個名爲'std :: shared_ptr'的C++ 11智能指針。 – 2013-02-28 01:07:17

回答

1

這是我會怎麼做。性能可以得到改善,但只要它不會成爲您的應用程序的瓶頸,我就不會爲此而煩惱。該算法簡單明瞭。

它使用remove_if有選擇地從第一個容器(myVector)中刪除指向第二個容器(myOtherVector)的元素所指向的對象的所有元素;然後,清除第二個容器。謂詞是通過lambda函數來實現:

#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();