簡體   English   中英

從帶有原始指針的向量中刪除std :: unique_ptr的最佳方法是什么?

[英]Best way to delete a std::unique_ptr from a vector with a raw pointer?

所以我有一個這樣的矢量:

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已觸發斷點”。 點擊繼續,我得到一個調試斷言失敗。

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

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

我就是這樣做的。 性能可以提高,但只要它不會被證明是您的應用程序的瓶頸,我不會打擾它。 該算法簡單明了。

它使用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();
}

如果你不能簡化你的問題,std :: set_difference或其中一個家伙( http://www.cplusplus.com/reference/algorithm/set_difference/ )怎么樣?

您需要指定一個比較函數來get()來自unique_ptr的原始指針

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM