8

所以我有一个像这样的向量:

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_ptrs 引用同一个对象。里面的元素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 已触发断点”。单击继续后,我得到了调试断言失败。

所以很明显我做错了什么,但我不知道是什么。使用原始指针从向量中擦除智能指针的正确方法是什么?

4

3 回答 3

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();    
于 2013-02-28T01:13:05.013 回答
3

我就是这样做的。性能可以提高,但只要它不会成为您的应用程序的瓶颈,我不会为此烦恼。该算法简单明了。

它用于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();
}
于 2013-02-28T01:13:29.840 回答
0

如果你不能简化你的问题,那么 std::set_difference 或它的其中一个(http://www.cplusplus.com/reference/algorithm/set_difference/)怎么样?

您需要指定一个比较函数来获取()来自 unique_ptr 的原始指针

于 2013-07-04T05:54:45.587 回答