1

我正在尝试std::reference_wrapper在另一个向量的所有元素上使用。但是当我删除原始元素时,我想自动删除引用向量中的元素。我做了一些解决方法,但它们很难看。有什么建议么?

#include <iostream>
#include <list>

struct A
{
    A(int x) : x(x){}
    int x;
};
std::list<std::reference_wrapper<A>> listRef;

struct B
{
    std::list<A> l;
    B()
    {
        l.emplace_back(42);
        listRef.emplace_back(l.back());
    }
    void foo()
    {
        customRemove(l.back());
    }
    void customRemove(const A & obj)
    {
        //l.remove(obj); // Error: binary '==': no operator found which takes 
        //a left-hand operand of type 'A' (or there is no acceptable conversion)
        // so I did
        l.remove_if([&](const A & obj2) { return &obj == &obj2; });
        // is there a way to automatically remove dangling references?
        listRef.remove_if([&](const A & obj2) { return &obj == &obj2; });
    }
};

int main()
{
    B b;
    std::cout << listRef.size() << '\t' << b.l.size() << '\n'; // prints 1  1
    b.foo();
    std::cout << listRef.size() << '\t' << b.l.size() << '\n'; // prints 0  0
}
4

1 回答 1

0

简而言之:不要这样做。std::reference_wrapper<A>与仅拥有原始指针列表相比,存储在列表中没有任何好处。

更好的方法是先存储std::shared_ptr在 l 中,然后再存储std::weak_ptrlistRef. 然后,如果你最终得到悬空引用,listRef你可以在使用它之前测试对象是否仍然存在:

std::list<std::weak_ptr<A>> listRef;

struct B
{
    std::list<std::shared_ptr<A>> l;
    B()
    {
        l.emplace_back(new A(42));
        listRef.emplace_back(l.back());
    }
    void foo()
    {
        customRemove(l.back());
    }
    void customRemove(std::shared_ptr< A > obj)
    {
        l.remove(obj);
        obj.reset();
        listRef.remove_if([&](const std::weak_ptr<A> & obj2) { return obj2.expired(); });
    }
};
于 2018-09-21T13:07:23.313 回答