最好的方法是从带有原始指针的向量中删除std :: unique_ptr? [英] Best way to delete a std::unique_ptr from a vector with a raw pointer?

查看:177
本文介绍了最好的方法是从带有原始指针的向量中删除std :: unique_ptr?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So I have a vector like so:

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

然后我有另一个向量,其中包含 SomeClass

Then I have another vector which contains raw pointers of SomeClass:

std::vector<SomeClass*> myOtherVector;

如果 myOtherVector 也将在 myVector 中,所以我想通过 myOtherVector 中的每个元素,并从 myVector 。然后清除向量。这是我想出来的:

If there is an element inside myOtherVector it will also be inside myVector, so I want to go through each element in myOtherVector and remove the same element from myVector. Then clear out the vector. This is what I came up with:

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()函数一个原始指针。这是我需要帮助,因为我不知道什么正确的方法来解决这个问题是。我改变了行:

This produces a compile time error because myVector holds unique pointers but I'm giving the remove() function a raw pointer. This is where I need help because I don't know what the proper way to solve this problem would be. I changed the line to:

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

这些都不正确,因为现在我有两个 std :: unique_ptr 引用同一个对象。 myVector 中的元素包含引用,并且上面行中唯一指针的构造是另一个引用。我甚至不知道如果构造一个新的指针,以获得相同的类型是概念上正确的方式去做这个。然后我改变了指向共享指针的唯一指针:

Frist of all this is incorrect because now I have two std::unique_ptrs referencing the same object. The element inside myVector contains a reference and the construction of the unique pointer in the above line is another reference. And I don't even know if constructing a new pointer to get the same type is conceptually the correct way to go about doing this. So then I changed the unique pointers to shared pointers:

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已触发断点。在点击continue后,我得到一个调试断言失败。

When I ran the application the myVector.erase() line resulted in a runtime error which said "ApplicationName.exe has triggered a breakpoint." upon clicking continue I got a debug assertion failure.

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

So obviously I'm doing something wrong, but I don't know what. What is the correct way to erase a smart pointer from a vector with a raw pointer?

推荐答案

。性能可以提高,但只要它不会被证明是您的应用程序的瓶颈,我不会打扰。

This is how I would do it. Performance could be improved, but as long as it won't prove to be a bottleneck for your application, I would not bother with that. The algorithm is simple and clear.

它使用 remove_if 选择性地从第一个容器中删除( myVector )指向第二个容器(myOtherVector)的元素所指向的对象的所有元素;然后,它清除第二个容器。该谓词通过lambda函数实现:

It uses remove_if to selectively remove from the first container (myVector) all the elements pointing to objects that are pointed to by elements of the second container (myOtherVector); then, it clears the second container. The predicate is implemented through a lambda function:

#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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆