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!
What you're looking for is std::bind instead of std::mem_fn:
#include <iostream>
#include <functional>
struct Object
{
void member()
{
std::cout << "yay!" << std::endl;
}
};
int main()
{
Object o;
auto fn = std::bind(&Object::member, o);
fn();
}
FWIW: There's a proposal for adding an overload to std::mem_fn accepting the object for inclusion in C++14.