'Using std::function/mem_fn in C++11 with member functions
Long story short, is there a simple/defined way to treat function objects/lambdas and member functions in a streamlined way?
If I understand right, if I use std::mem_fn, I need to pass an object of the correct type to the function call, i.e.
Object o;
ftncall std::mem_fun(&Object::function);
ftncall(o);
Ideally, there would be some way to 'attach' o to that function object, perhaps as a std::weak_ptr, so we know if o got deleted. For example, if there were a way to do something vaguely like this:
Object o;
ftncall std::mem_fn(&Object::function, o); // Or maybe std::mem_fn<Object>
ftncall();
Now, obviously, this doesn't exist (to my knowledge). Is there a way to wrap std::mem_fn in such a way that I don't loose the generality (and niceness) of std::mem_fn, but can 'attach' o, AND still play nicely with the other function type, like std::function? Ideally, I'd still be able to use operator() in the way that I do with std::function.
Currently the best solution I can think of is a class that looks like this:
template<class T>
class MemFunWrapper {
public:
MemFunWrapper(T* t, std::mem_fun funct) : m_t(t), m_function(funct) {}
std::mem_fun operator*() { return m_function; }
T* get() { return m_t; }
private:
T* m_t;
std::mem_fun m_function;
}
Then you could use it thusly:
(*MemFunWrapper)(MemFunWrapper->get(), args...);
But that seems pretty unwieldy to me. Also, I'd have to create an equivalent class for std::function for that to be usable in the analogous way, and that seems silly since I can already just use std::function. Ideally, I'd also be able to use the end product without knowing if I'm calling a member function or a regular function. I know I'm asking a lot - any direction would be helpful. Many thanks!
Solution 1:[1]
In C++11, I usually find this is easiest done with lambdas:
std::shared_ptr<Object> o = std::make_shared<Object>();
auto ftncall = [o](){ if (o) o->function(); }
ftncall();
or, with no shared lifetime:
Object o;
auto ftncall = [&o](){ o.function(); }
ftncall();
or with a weak ptr:
std::shared_ptr<Object> o = std::make_shared<Object>();
std::weak_ptr<Object> wo = o;
auto ftncall = [ow](){ if (auto o = wo.lock()) o->function(); }
ftncall();
If you need type erasure, just stuff it into a std::function<void()>.
Lambdas in C++11 can do much the same job as bind does without having to rely on library functions to do it, and I personally find them much more readable.
There are some situations where bind can do a better job in C++11, but they are corner cases at this point (in C++1y, more corners will be cut off as well).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
