【问题标题】:How to get an element based on raw_ptr from an unordered_set keyed on shared_ptr如何从以 shared_ptr 为键的 unordered_set 中获取基于 raw_ptr 的元素
【发布时间】:2016-04-22 22:39:38
【问题描述】:

我想知道是否有任何方法可以让我根据其原始指针从unordered_set 中检索一个元素,该shared_ptr 键控。

unordered_set< shared_ptr<MyObj> > sets;
auto myobj = make_shared<MyObj>();
sets.insert(myobj);

// Find the element myobj
sets.find(myobj);

// How to find the element based on the underlying raw pointer?
sets.find(my.obj.get()); <---- apparently this gives compile error

// This method works but it will double free myobj though (not correct)
sets.find(shared_ptr<MyObj>(my.obj.get()));

【问题讨论】:

    标签: c++ c++14 shared-ptr unordered-set


    【解决方案1】:

    仅使用底层原始指针来查找您要查找的内容可以通过使用带有异构查找的 std::set 来完成。

    这里需要注意的是,您必须使用集合而不是 unordered_set。如果您真的需要无序(我发现这种情况很少见),那么请使用 alexm 的 shared_from_this() 解决方案。否则,异构查找是一种相当优雅和灵活的方法。

    --

    使用异构查找,您只需要定义一个特殊的比较器,该集合将用于其排序功能。

    以下应该可以解决问题:

    struct Raw_comp{
      using is_transparent = std::true_type;
      bool operator()(const shared_ptr<MyObj>& lhs, const shared_ptr<MyObj>& rhs) const{
       return lhs < rhs;
    }
      bool operator()(shared_ptr<MyObj>& lhs, MyObj* rhs) const{
       return std::less<MyObj>()(lhs.get(), rhs);
    }
      bool operator()(const MyObj* lhs, const shared_ptr<MyObj>& rhs) const{
       return std::less<MyObj>()(lhs, rhs.get());
    }
    };
    

    然后声明集合:

    set< shared_ptr<myObj>, Raw_cmp> sets;
    

    Here is more information on heterogeneous lookup if you are interested

    【讨论】:

    • 1) GivenMyObj *p1, *p2;, p1 &lt; p2 没有很好的定义,但std::less&lt;MyObj*&gt;{}(p1, p2) 是。 2)当你不想要所有权时,通过价值传递shared_ptrs 是错误的; shared_ptr const&amp; 在这里是完全有效和有用的。 3) 您的第一个 operator() 没有使用应有的 .get()。 4) 所有operator() 重载都应该是const
    • 你是绝对正确的。感谢您在我草率的代码上给我打电话。我不一定同意#2 是错误的,但它确实表明了错误的意图,你是对的, const& 是更好的选择。至于 #3,
    【解决方案2】:

    您可以将MyObj 声明为:

    class MyObj : public std::enable_shared_from_this<MyObj>
    {
         ....
    }
    

    这添加了一个方法,该方法返回给定对象实例的共享指针。

    MyObj * rawptr = myobj.get();
    sets.find(rawptr->shared_from_this());
    

    请注意,在对对象调用 shared_from_this() 之前,必须有一个 std::shared_ptr 拥有它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-27
      • 1970-01-01
      • 2013-06-05
      • 2021-09-02
      • 2016-10-07
      • 1970-01-01
      • 2015-07-11
      相关资源
      最近更新 更多