c++ - Is object std::shared_ptr findable by its std::weak_ptr? -
so have std::vector<std::shared_ptr<t>> mylistoft;
, have std::weak_ptr<t> ptrtoonet;
created 1 of pointers used fill container (say have inside callback function). std::find
on container , weak_ptr
give me iterator original shared_ptr
(if such 1 exists in collection)? guaranteed somewhere in standard or implementation dependent?
we can away without locking weak_ptr
using std::weak_ptr::owner_before
. i'll use more verbose solution necessary , introduce owner_equal
, counterpart std::owner_less
:
template<typename t> class owner_equal { private: template<typename l, typename r> static bool e(l const& l, r const& r) { return !(l.owner_before(r)) && !(r.owner_before(l)); } public: using s = std::shared_ptr<t>; using w = std::weak_ptr<t>; bool operator()(s const& l, w const& r) const { return e(l, r); } bool operator()(w const& l, s const& r) const { return e(l, r); } };
with function object type, can customize std::find_if
:
using t = int; std::vector<std::shared_ptr<t>> mylistoft = {std::make_shared<int>(0), std::make_shared<int>(1), std::make_shared<int>(2)}; int const pos = 1; std::weak_ptr<t> ptrtoonet = mylistoft[pos]; auto pred = [&ptrtoonet](std::shared_ptr<t> const& e) { return owner_equal<t>{}(e, ptrtoonet); }; auto const r = std::find_if(begin(mylistoft), end(mylistoft), pred); assert(r - begin(mylistoft) == pos);
the lambda can replaced bind-expression such as:
auto pred = std::bind(owner_equal<t>{}, std::cref(ptrtoonet), std::placeholders::_1);
@davidhigh suggested optimization:
template<typename fwdit, typename t> fwdit findweakptr(fwdit b, fwdit e, std::weak_ptr<t> const& w) { if(w.expired()) return e; else { auto pred = [&w](std::shared_ptr<t> const& e) { return owner_equal<t>{}(e, w); }; return std::find_if(b, e, pred); } }
(not tested)
this changes behaviour: if weak_ptr
"empty", e.g. having been created empty shared_ptr
or via default ctor, compare equal empty shared_ptr
via owner_equal
. however, weak_ptr::expired
true in case. therefore, optimized version not find empty shared pointers in range.
should empty shared pointers found in range?
consider:
using t = int; std::vector<std::shared_ptr<t>> mylistoft = {std::shared_ptr<t>(), std::shared_ptr<t>()}; int const pos = 1; std::weak_ptr<t> ptrtoonet = mylistoft[pos]; auto const r = my_weak_ptr_find(begin(mylistoft), end(mylistoft), ptrtoonet); auto const r_pos = r - begin(mylistoft);
empty shared pointers equal. therefore, if allow finding empty shared pointers, r_pos != pos && r != end(mylistoft)
possible. example, first version of algorithm in answer yields r_pos == 0
.
for additional context, see:
Comments
Post a Comment