我有一个像这样的向量:
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已经触发了一个断点。"在点击继续时,我得到了一个调试断言失败。
显然我做错了什么,但我不知道是什么。什么是正确的方法从一个原始指针的矢量擦除智能指针?
我是这样做的。性能是可以改进的,但只要它不会成为应用程序的瓶颈,我就不会为此费心。算法简单明了。
它使用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::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();
如果你不能简化你的问题,如何std::set_difference或它的一个同类(http://www.cplusplus.com/reference/algorithm/set_difference/)?
您需要指定一个比较函数来从unique_ptr