test std::function validity after bind to member function

别等时光非礼了梦想. 提交于 2021-01-28 06:11:03

问题


For the struct:

struct A {
    int var = 10;
    void check() {
        std::cout << "var is " << var << std::endl;
    }
};

Say I create a std::function object of A::check(), using a dynamically allocated a object:

auto a_ptr = std::make_unique<A>();
std::function<void()> f = std::bind(&A::check, a_ptr.get());
//...later/elsewhere...
f();

It would be nice for safety if I could test f to see if the bound A object is still alive. Is it possible to retrieve that information from f directly? Assume a_ptr is not accessible from the call point, so I can't test against a_ptr directly. Using std::function's operator bool, or testing f against nullptr don't work.


回答1:


So you basically want your function object to test for the existence of the A instance managed by a_ptr, i see 3 ways of doing this with the current c++ std features.

-- Lambda with a reference to the unique_ptr

auto a_ptr = std::make_unique<A>();
std::function<void()> f = [&] { if (a_ptr) a_ptr->check(); };
//...later/elsewhere...
f();

This requires that the pointer is still alive anytime the function object is alive.

-- Lambda with a copy of the shared_ptr

auto a_ptr = std::make_shared<A>();
std::function<void()> f = [=] { if (a_ptr) a_ptr->check(); };
//...later/elsewhere...
f();

Same thing but without requirements on the lifetime relationship at the expense of some additional performance cost which is mainly the copy of a shared pointer, probably totally worth the headache it saves in most cases (i'm going to be burned by the optimisation guys for this one).

-- Custom deleter in your smart pointer that resets your function

std::function<void()> f;
auto a_ptr = std::unique_ptr<A, std::function<void(A*)>>(new A, [&](A*){ f = nullptr;});
f = std::bind(&A::check, a_ptr.get());
//...later/elsewhere...
a_ptr.reset();
if (f)
  f();

This requires that somehow your deleter can access the function to reset it, whether it is directly or through a storage system in your classes (containers of functions are a nice design imo).


You can also create more elaborated systems with your own primitives but that would lead you further away from the standard library. Ultimately you'll have to choose what's best in your situation mainly based on the lifespan and ownership relationships of your objects.




回答2:


Well, this one is easy, use std::shared_ptr.

when you think about it , you basically want to ensure that some entity in you program is valid as long as something is using it.
In other words, you are looking for a shared_ptr.

Otherwise, the design looks a bit weird, if some single entity in your program is owning a_ptr, it should be the single owner of all the std::functions which uses this resource, which is not your intention. if that owner is not the owner of the std::function you are highly increasing the probability of segmentation faults, heap corruption and other stuff you don't want.



来源:https://stackoverflow.com/questions/34785311/test-stdfunction-validity-after-bind-to-member-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!