Abstracting pointer-to-member-function: safety and alternatives - c++

In this problem, assume that we have handled all pointers in a nice, careful manner - to prevent question bloat I don't want to include my cleanup code here!
Let's say we have two classes, Foo and Bar with class definitions as follows:
class Foo
{
public:
Foo();
void fooFn();
};
class Bar
{
public:
Bar();
void barFn();
};
Assume that it is necessary that Foo and Bar have no inheritance relationship, but we need to call both fooFn and barFn in response to some stimulus. We can create a controller class with a container from which to call fooFn and barFn on specific instances of Foo and Bar - a static std::vector for example - but we run into an issue: pointers to member functions of Foo and Bar instances are of different types.
By using a static vector< std::function<void()>* > in the controller class, we can make a workaround. Foo and Bar instances can have a function which adds pointers to the vector through a lambda function which captures this:
void Foo::registerFnPointer()
{
ControllerClass::function_vector.push_back( new [this](){ return this->fooFn(); } );
}
I have tested this method, and it appears to work without any problems. That said, I am concerned about the issues that could be caused by circumventing the type difference mentioned before... Am I worrying over nothing? Is there a better way to accomplish equivalent functionality?

The only problem I see has actually nothing to do with the functors but has to do with object lifetime. That is: I'm not sure how you ensure that you always de-register the functors registered with ControllerClass whenever an Foo or Bar instance gets destroyed.
You mention however that you do proper memory management.
In my opinion you do not need to store a pointer to function<void()>, you can simply store function as value (that is have a vector<function<void()>>).
Prior to C++11 and lambdas, to achieve the same effect you would have used a (boost) function also but you would would have used boost::bind with with the address of the fooFn and the first parameter bound to a pointer (or reference) to the Foo object instance.
This would have created an instance of the function that holds all of the information needed to call the fooFn method on the given object. You could then store the instance in a vector to call it at a later time (and had the same problem of making sure no boost::function bound to a destroyed object remains registered)
Edit:
For the sake of completeness, the link to the Boost bind documentation specific for binding members: http://www.boost.org/doc/libs/1_56_0/libs/bind/bind.html#with_member_pointers
What you are doing is actually quite similar only that you are now using a lambda to capture the object pointer and to define the function to be called.
So I see no problem with what you are doing (other then the one I already mentioned).

You could use an adapter class. This might be overkill for what you're doing, but it may work.
The benefits of doing it this way are:
You don't have to change the original classes. Creating void Foo::registerFnPointer() is ugly.
You don't have to use your static std::vector.
You don't have to deal with function pointers.
So let's say you have two different classes like this:
struct Foo
{
void fooFn () {
std::cout << "Foo::fooFn ()" "\n" ;
}
};
struct Bar
{
void barFn () {
std::cout << "Bar::barFn ()" "\n" ;
}
};
The goal is to put them into a container and call their respective *Fn () member-functions.
An adapter would look something like this:
struct Adapter_Base
{
virtual ~Adapter_Base () {} ;
virtual void adapterFn () = 0 ;
};
template <typename T>
struct Adapter : Adapter_Base
{
T tVal ;
Adapter (const T &tVal) : tVal (tVal) {}
void adapterFn () ;
};
template <>
void Adapter <Foo>::adapterFn ()
{
tVal.fooFn () ;
}
template <>
void Adapter <Bar>::adapterFn ()
{
tVal.barFn () ;
}
And you could use it like this:
int main ()
{
std::vector <std::unique_ptr <Adapter_Base> > v1 ;
std::unique_ptr <Adapter_Base> u1 (new Adapter <Foo> (Foo ())) ;
std::unique_ptr <Adapter_Base> u2 (new Adapter <Bar> (Bar ())) ;
v1.push_back (std::move (u1)) ;
v1.push_back (std::move (u2)) ;
for (auto &adapter : v1) {
adapter->adapterFn () ;
}
return 0 ;
}

Related

lambda expression to assign a member function pointer

I need the syntax for a lambda expression that will return a pointer to a member function.
For example I have class A:
class A
{
int x;
void (A::*SomeFunction)();
}
I want to set SomeFunction to a lambda. I tried doing it like this:
A a();
a.SomeFunction = [this](){ printf("Hello from lambada %d",this->x);};
The problem is that:
[this](){ printf("Hello from lambda %d",this->x);};
does not give me a pointer to a member function of class A. it gives me a pointer to a normal function. How do i declare inside the lambda that this is a member function of A.
Alternativly if such a thing isn't possible in cpp. How do you suggest I'll access variable x of class A from the function that SomeFunction is pointing at without using virtual functions (this kind of code will run about 700 times per second).
Edit:
To make it clear I do care about performance. but the main reason why I need this is specific design problems not performance.
I understand this is probably not possible to do in cpp.
Workarounds suggestions would be welcomed.
That is not possible for several reasons.
First, a pointer to member function is different in type from a pointer to stand-alone function, and non-capturing lambdas can only be converted to pointers to standalone functions.
Second, your lambda is capturing, and as such, it can not be converted to a pointer to function at all, and can only remain a functor of unspecified type.
However, you shouldn't think too much into it and just store a lambda in a std::function. Granted, you will end with virtual dispatch and some performance degradation associated with that, but 700 times a second is nothing, and you will never detect a hit because of virtual dispatch.
It's impossible to add extra methods to a class after its definition. Therefore, since there are no methods in your class A, it's impossible to ever set A::SomeFunction to point to any non-static method of A. As a workaround, you could have
void (*SomeFunction)(A*);
and
A a {}; // note {} instead of ()
a.SomeFunction = [](A* a){ /* do something with a->x */ };
From the comments:
This is part of an ECS implemention. and I am simply not willing to create a new class for etch system i want to give the user the option to declare the system in the scene constructor or inheriate from the system class.
You want different behavior from the same class without any indirection? You'll have to give up one.
But you don't have to write a class for each system either. You can make the class a template, so the compiler can generate a class for each systems:
template<typename T>
struct A : private T {
A(T function) noexcept : T{std::move(function)} {}
void SomeFunction() {
(*this)(this);
}
int x = 0;
};
It can then be used like that:
auto lambda = [](auto a){ printf("Hello from lambda %d",a->x); };
auto my_a = A{lambda}; // Generate a new A type from lambda
my_a.SomeFunction(); // calls the lambda!
Well following up for future people here's a workaround to make it look a bit nicer.
I created a template class
template <class Parent,class Return, class...Params>
struct MemberLambda
{
Parent* self; // pointer to self
void (*lambda)(Parent * self,Params...);//the lambda
MemberLambda() = default;//Constructor
MemberLambda(Parent* self, void(*lambda)(Parent* self,Params...)) :
self(self),lambda(lambda) {};//Constructor
Return operator()(Params... p) const { return lambda(self,p...); };
void operator=(void (*lambda)(Parent* self, Params...)) {
this->lambda = lambda;
}
};
Usage in class:
class A {
public:
int someMember;
MemberLambda<A, void, int, int> func =
MemberLambda<A, void, int, int>(this, nullptr);
};
*Note in the example I set the lambda to nullptr but it can be set to a lambda expression.
In the example, the lambda is a member of A takes two ints and returns void.
User usage:
A a;
a.someMember = 3;
a.func = [](A* self, int a, int b){ std::cout << self->someMember + a + b; };
a.func(5,6);
Will output 14, which is 3 + 5 + 6.

C++: Function pointer that holds a method from a specific instance

So I'm currently working on an input manager for a C++ game. I was thinking about doing it as a map<char, list<Listener::method>>, so that when I register a button pressed, I call all the methods registered for the specific key.
Problem is, done like that I have to specify the instance which I want to call the method from. Is there a way to hold inside a variable not only the method but the caller instance?
Something like:
class Foo
{
public:
Foo ();
~Foo ();
void DoSomething();
};
Foo fooObject;
void(Foo::*fPtr)(void) = &fooObject::DoSomething;
(*fPtr)();
And that would call fooObject's DoSomething()
Is it possible?
If not, could someone point me to a Event-Listener pattern? Doesnt have to be overcomplicated or threadsafe. Just the basic structure.
The problem with member function pointers is you need an instance of the class to call them on. You can't achieve this with just a pointer because the pointer only points to the function, and not the additional object you need to pass to the function (remember all member functions have an implicit first parameter that takes the class type).
You can use a std::function to have a function object that holds the object to call and the function to call on it. If you have
std::function<void()> func = [&](){ return fooObject.DoSomething(); }; // Bind with a reference. Use this if the object will live as long as the function to save on a copy
std::function<void()> func = [=](){ return fooObject.DoSomething(); }; // Bind with a copy. Use this if the function will outlive the object
then when you call func using func() it will run the body of he lambda which calls DoSomething on fooObject.
You can also use std::bind to bind a member function pointer to a object to call it on but lambdas are generally preferred as the syntax is easy to use.
Is there a way to hold inside a variable not only the method but the caller instance?
Yes, you can bind method and object together.
Since C++11 you have bind utility.
A minimal example from your concept:
struct Foo {
void foo();
};
void bar() {
// your map
std::map<char, std::function<void()>> actions;
// Bind method and object together inside fn
Foo foo;
auto fn = std::bind(&Foo::foo, &foo);
// Insert fn into map
actions.emplace('f', fn);
// call fn from map! Be careful about object lifetime
actions['f']();
}
Godbolt code
Be careful because the "bind object" (fn in my example) will just store a reference to the object foo. Therefore, if you invoke fn after the object foo has been destroyed you will get an undefined behaviour.
In case you want to take care about object lifetime, you can copy it with a lambda function. For example:
auto fn = [foo]() { foo.foo(); }
Or use a custom structure and store a copied object inside.
There is no such thing as a "method from a specific instance".
You can hold a pointer to a member function of a class. Such pointers are not bound to any specific object.
You can use that function pointer on any object of the class.
Given
class Foo
{
public:
Foo ();
~Foo ();
void DoSomething();
};
Any class can hold a pointer to the DoSomething member function (you're calling it a method).
void(Foo::*fPtr)(void) = &Foo::DoSomething;
You would need an object to be able to call the member function. The calling syntax is a bit obtuse but here it is.
Foo foo = <some function call>;
(foo.*fPtr)();
You could use the bind-functionality to get function object having function parameteras already bound to arguments. By that, you can bind the object reference, which is implicitly the first parameter in any non-static member function, to the respective object for which you'd like to have the callback:
class Foo
{
public:
int x;
Foo (int _x) : x(_x) {} ;
void doSomething() { cout << x << endl; }
};
int main() {
Foo fooObject1(1);
Foo fooObject2(2);
std::function<void ()> fx1 = std::bind(&Foo::doSomething,&fooObject1);
std::function<void ()> fx2 = std::bind(&Foo::doSomething,&fooObject2);
std::vector<std::function<void ()>> callbacks;
callbacks.push_back(fx1);
callbacks.push_back(fx2);
for (auto f : callbacks) {
f();
}
}
Output:
1
2

Passing arbitrary information for a functional parameter to use

In C++:
I have an object I'll call Foo.
Foo performs statistical operations on a supplied data set. The first step of the process involves a fitting function, and a functional parameter can be supplied so that the user can specify the type of model being used.
The problem is that I now have a situation where the function parameter needs to have access to data that does not exist in Foo but rather in the object that is using Foo, which I will call Bar.
So Bar calls Foo to have Foo operate on Bar's data. Bar has a specific function it wants to use as the functional parameter but this function requires information specific to Bar.
I don't want to pass Bar because if I code Foo up to receive Bar, then every time I have a new object that needs additional info passed to Foo, I will have to adjust the Foo class to accept that object.
I don't want to modify the functional parameter input in Foo because then I'll have to modify the functional parameter input for every new usage case as well.
I considered using a base class I'll call StandardFunc. Then, via virtual methods, Bar could create an object called ModifiedFunc that derives from StandardFunc. It could override the StandardFunc's function and also supply the additional info as class parameters. This doesn't work either because to avoid slicing I have to type-cast ModifiedFunc to StandardFunc. This means that inside Foo I have to change the type-cast line for every new object name.
Can someone please point me in the right direction for how I can allow users to pass either a functional parameter alongside arbitrary parameters the function requires without having to recode the Foo class for every different usage case? I'm really stuck on this.
EDIT: pseudo code example:
class Foo
{
void processHandler(function)
void process();
void process(function);
void theUsualFunction(vector); //the default function used by process
vector vec;
};
void Foo::process()
{
processHandler(theUsualFunction);
}
void Foo::process(function f)
{
processHandler(f)
}
void Foo::processHandler(function f)
{
f(vec)
//do other stuff to vec
}
void Foo::theUsualFunction(vector v)
{
//default vec processor
}
class Bar
{
int x;
int y;
vector vec;
void theModifiedFunction(vector);
void callFooToProcess();
};
void Bar::theModifiedFunction(vector v)
{
//process v, but in a way that requires x and y
}
void Bar::callFooToProcess()
{
Foo foo;
foo.setVector(vec);
process(theModifiedFunction);
}
So this code is kind of an example of what I want to achieve, but it doesn't work as written. The reason is because I have no way of getting Bar::x and Bar::y to the function Foo::processHandler(function) without modifying the arguments for Foo::processHandler, and I don't want to do that because then every new class like Bar and every new theModifiedFunction that requires different data will require me to rewrite the arguments for processHandler.
This doesn't work either because to avoid slicing I have to type-cast ModifiedFunc to StandardFunc.
Slicing only occurs if you pass the argument by value. You should pass it as a pointer, that's how polymorphism is supposed to work.
Also, you can keep passing the argument by value if you make your class a template:
template<class Func>
class Foo {
void doStuff(Func func) {
...
}
}
Keep in mind though, that in this case Func has to be known at compile-time.
Although there may be other ways of handling this situation, I would suggest considering to have Bar contain Foo. This is called a has-a relationship [wiki]. The advantage of this is that you can use Foo as-is without modifying anything within Foo, as well as Bar need not pass around its private data. Hope the following code snippet would help you to understand the concept.
public class Bar
{
private Foo myFoo;
private int myInfo;
void a()
{
myFoo.doStuff(myInfo);
}
}

C++ One std::vector containing template class of multiple types

I need to store multiple types of a template class in a single vector.
Eg, for:
template <typename T>
class templateClass{
bool someFunction();
};
I need one vector that will store all of:
templateClass<int> t1;
templateClass<char> t2;
templateClass<std::string> t3;
etc
As far as I know this is not possible, if it is could someone say how?
If it isn't possible could someone explain how to make the following work?
As a work around I tried to use a base, non template class and inherit the template class from it.
class templateInterface{
virtual bool someFunction() = 0;
};
template <typename T>
class templateClass : public templateInterface{
bool someFunction();
};
I then created a vector to store the base "templateInterface" class:
std::vector<templateInterface> v;
templateClass<int> t;
v.push_back(t);
This produced the following error:
error: cannot allocate an object of abstract type 'templateInterface'
note: because the following virtual functions are pure within 'templateInterface'
note: virtual bool templateInterface::someFunction()
To fix this error I made the function in templateInterface not a pure virtual by providing a function body, this compiled but when calling the function the overide is not used, but instead the body in the virtual function.
Eg:
class templateInterface{
virtual bool someFunction() {return true;}
};
template <typename T>
class templateClass : public templateInterface{
bool someFunction() {return false;}
};
std::vector<templateInterface> v;
templateClass<int> i;
v.push_back(i);
v[0].someFunction(); //This returns true, and does not use the code in the 'templateClass' function body
Is there any way to fix this so that the overridden function is used, or is there another workaround to store multiple template types in a single vector?
Why your code doesn't work:
Calling a virtual function on a value doesn't use polymorphism. It calls the function which is defined for the type of this exact symbol as seen by the compiler, not the runtime type. When you insert sub types into a vector of the base type, your values will be converted into the base type ("type slicing"), which is not what you want. Calling functions on them will now call the function as defined for the base type, since not it is of that type.
How to fix this?
The same problem can be reproduced with this code snippet:
templateInterface x = templateClass<int>(); // Type slicing takes place!
x.someFunction(); // -> templateInterface::someFunction() is called!
Polymorphism only works on a pointer or reference type. It will then use the runtime type of the object behind the pointer / reference to decide which implementation to call (by using it's vtable).
Converting pointers is totally "safe" with regard to type slicing. Your actual values won't be converted at all and polymorphism will work as expected.
Example, analogous to the code snippet above:
templateInterface *x = new templateClass<int>(); // No type slicing takes place
x->someFunction(); // -> templateClass<int>::someFunction() is called!
delete x; // Don't forget to destroy your objects.
What about vectors?
So you have to adopt these changes in your code. You can simply store pointers to actual types in the vector, instead of storing the values directly.
When working with pointers you also have to care about deleting your allocated objects. For this you can use smart pointers which care about deletion automatically. unique_ptr is one such smart pointer type. It deletes the pointee whenever it goes out of scope ("unique ownership" - the scope being the owner). Assuming the lifetime of your objects is bound to the scope this is what you should use:
std::vector<std::unique_ptr<templateInterface>> v;
templateClass<int> *i = new templateClass<int>(); // create new object
v.push_back(std::unique_ptr<templateInterface>(i)); // put it in the vector
v.emplace_back(new templateClass<int>()); // "direct" alternative
Then, call a virtual function on one of these elements with the following syntax:
v[0]->someFunction();
Make sure you make all functions virtual which should be possible to be overridden by subclasses. Otherwise their overridden version will not be called. But since you already introduced an "interface", I'm sure you are working with abstract functions.
Alternative approaches:
Alternative ways to do what you want is to use a variant type in the vector. There are some implementations of variant types, the Boost.Variant being a very popular one. This approach is especially nice if you don't have a type hierarchy (for example when you store primitive types). You would then use a vector type like std::vector<boost::variant<int, char, bool>>
Polymorphism only works through pointers or references. You'll
need the non-template base. Beyond that, you'll need to decide
where the actual objects in container will live. If they're all
static objects (with sufficient lifetime), just using
a std::vector<TemplateInterface*>, and inserting with
v.push_back(&t1);, etc., should do the trick. Otherwise,
you'll probably want to support cloning, and keep clones in the
vector: preferably with Boost pointer containers, but
std::shared_ptr can be used as well.
The solutions given so far are fine though be aware that in case you were returning the template type other than bool in your example , none of these would help as the vtable slots would not be able to be measured before hand. There are actually limits , from a design point of view , for using a template oriented polymorphic solution.
Solution nr. 1
This solution inspired by Sean Parent's C++ Seasoning talk. I highly recommend to check it out on youtube. My solution simplified a bit and the key is to store object in method itself.
One method only
Create a class that will invoke method of stored object.
struct object {
template <class T>
object(T t)
: someFunction([t = std::move(t)]() { return t.someFunction(); })
{ }
std::function<bool()> someFunction;
};
Then use it like this
std::vector<object> v;
// Add classes that has 'bool someFunction()' method
v.emplace_back(someClass());
v.emplace_back(someOtherClass());
// Test our vector
for (auto& x : v)
std::cout << x.someFunction() << std::endl;
Several methods
For several methods use shared pointer to share object between methods
struct object {
template <class T>
object(T&& t) {
auto ptr = std::make_shared<std::remove_reference_t<T>>(std::forward<T>(t));
someFunction = [ptr]() { return ptr->someFunction(); };
someOtherFunction = [ptr](int x) { ptr->someOtherFunction(x); };
}
std::function<bool()> someFunction;
std::function<void(int)> someOtherFunction;
};
Other types
Primitive types (such as int, float, const char*) or classes (std::string etc.) may be wrapped in the same way as object class do but behave differently. For example:
struct otherType {
template <class T>
otherType(T t)
: someFunction([t = std::move(t)]() {
// Return something different
return true;
})
{ }
std::function<bool()> someFunction;
};
So now it is possible to add types that does not have someFunction method.
v.emplace_back(otherType(17)); // Adding an int
v.emplace_back(otherType("test")); // A string
Solution nr. 2
After some thoughts what we basically done in first solution is created array of callable functions. So why not just do the following instead.
// Example class with method we want to put in array
struct myclass {
void draw() const {
std::cout << "myclass" << std::endl;
}
};
// All other type's behaviour
template <class T>
void draw(const T& x) {
std::cout << typeid(T).name() << ": " << x << std::endl;
}
int main()
{
myclass x;
int y = 17;
std::vector<std::function<void()>> v;
v.emplace_back(std::bind(&myclass::draw, &x));
v.emplace_back(std::bind(draw<int>, y));
for (auto& fn : v)
fn();
}
Conclusion
Solution nr. 1 is definitely an interesting method that does not require inheritance nor virtual functions. And can be used to other stuff where you need to store a template argument to be used later.
Solution nr. 2, on the other hand, is simpler, more flexible and probably a better choice here.
If you're looking at a container to store multiple types, then you should explore boost variant from the popular boost library.

pass lambda expression as member function pointer in c++

I have a framework function which expects an object and a member function pointer (callback), like this:
do_some_work(Object* optr, void (Object::*fptr)()); // will call (optr->*fptr)()
How can I pass a lambda expression to it? Want to do somethink like this:
class MyObject : public Object
{
void mystuff()
{
do_some_work(this, [](){ /* this lambda I want to pass */ });
}
};
The meaning of it all is to not clutter the interface of MyObject class with callbacks.
UPD
I can improve do_some_work in no way because I don't control framework and because actually it isn't one function, there're hundreds of them. Whole framework is based on callbacks of that type. Common usage example without lambdas:
typedef void (Object::*Callback)();
class MyObject : public Object
{
void mystuff()
{
do_some_work(this, (Callback)(MyClass::do_work));
}
void do_work()
{
// here the work is done
}
};
SOLUTION Here's my solution based on Marcelo's answer:
class CallbackWrapper : public Object
{
fptr fptr_;
public:
CallbackWrapper(void (*fptr)()) : fptr_(fptr) { }
void execute()
{
*fptr_();
}
};
class MyObject : public Object
{
void mystuff()
{
CallbackWrapper* do_work = new CallbackWrapper([]()
{
/* this lambda is passed */
});
do_some_work(do_work, (Callback)(CallbackWrapper::execute));
}
};
Since we create the CallbackWrapper we can control it's lifetime for the cases where the callback is used asynchonously. Thanks to all.
This is impossible. The construct (optr->*fptr)() requires that fptr be a pointer-to-member. If do_some_work is under your control, change it to take something that's compatible with a lambda function, such as std::function<void()> or a parameterised type. If it's a legacy framework that isn't under your control, you may be able to wrap it, if it's a function template, e.g.:
template <typename Object>
do_some_work(Object* optr, void (Object::*fptr)());
Then, you can implement a wrapper template:
template <typename F>
void do_some_work(F f) {
struct S {
F f;
S(F f) : f(f) { }
void call() { f(); delete this; }
};
S* lamf = new S(f);
do_some_work(lamf, &S::call);
}
class MyObject // You probably don't need this class anymore.
{
void mystuff()
{
do_some_work([](){ /* Do your thing... */ });
}
};
Edit: If do_some_work completes asynchronously, you must allocate lamf on the heap. I've amended the above code accordingly, just to be on the safe side. Thanks to #David Rodriguez for pointing this out.
There are deeper problems with the approach that you are trying to take than the syntactical mismatch. As DeadMG suggests, the best solution is to improve the interface of do_some_work to take a functor of some sort (std::function<void()> in C++11 or with boost, or even a generic F on which operator() is called.
The solution provided by Marcelo solves the syntactical mismatch, but because the library takes the first element by pointer, it is the responsibility of the caller to ensure that the object will be alive when the callback is executed. Assuming that the callback is asynchronous, the problem with his solution (and other similar alternatives) is that the object can potentially be destroyed before the callback is executed, causing undefined behavior.
I would suggest that you use some form of plimp idiom, where the goal in this case would be to hide the need for callbacks (because the rest of the implementation might not need to be hidden you could use just another class to handle the callbacks but store it by value, if you don't want do have to dynamically allocate more memory):
class MyClass;
class MyClassCallbacks {
MyClass* ptr;
public:
MyClassCallbacks( MyClass* ptr ) : ptr(ptr) {}
// callbacks that execute code on `ptr`
void callback1() {
// do some operations
// update *ptr
}
};
class MyClass {
MyClassCallbacks callbackHandler;
public:
void mystuff() {
do_some_work( &callbackHandler, &MyClassHandler::callback1 );
}
};
In this design, the two classes are separated but represent a unique single entity, so it is fine to add a friend declaration and let MyClassCallbacks access the internal data in MyClass (both of them are one single entity, divided only to provide a cleaner interface, but coupling is already high, so adding the extra coupling requiered by friend is no problem).
Because there is a 1-1 relationship between MyClass and MyClassCallbacks instances, their lifetimes are bound and there would be no lifetime issues, except during destruction. During destruction you must ensure that there is no callback registered that can kick in while the MyClass object is being destroyed.
Since you are at it, you might want to walk the extra mile and do a proper pimpl: move all of the data and implementation into a different type that is held by pointer, and offer a MyClass that stores a pointer and offers just the public functions, implemented as forwarders to the pimpl object. This could be somehow tricky as you are using inheritance, and the pimpl idiom is a bit cumbersome to implement on type hierarchies (if you need to extend MyClass, deriving from Object could be done in the pimpl object, rather than the interface type).
I don't think you can do that. Your do_some_work() is declared to accept pointer to methods of class Object, so such should be provided. Otherwise optr->*fptr is invalid since the lambda is not member of Object. Probably you should try using std::function and adding the needed members of Object in its closure.
You must use std::function<void()>. Both function and member function pointers are highly unsuited to being callbacks.