Let's just say I have a Window class, and that Window class has event handlers in the form of std::function:
struct Event {};
struct Window
{
std::function<void(Event)> handler;
};
Window wnd;
wnd.handler = [] (Event) { /*some fancy handler*/ };
From inside the handler I don't have access to the window itself, so I can either pass the window pointer to the handler, or I can implicitly have access inside the handler function to the window by capturing it. However in the capturing case I think I run into this problem:
struct Event {};
struct Window
{
std::function<void(Event)> handler;
int member;
};
int main()
{
Window wnd1;
// Capture the window so I can access it inside the handler function
Window wnd2{ [&wnd2](Event) { wnd2.member = 3; } };
wnd1 = std::move(wnd2);
// wnd1 contains a lambda object pointing to wnd2, that's invalid.
Window wnd3 { [&wnd3](int) { wnd3.member = 7; } };
std::vector<Window> wnd_vector{ wnd3 }; // Now when vector reallocates the lambda // object is invalid because of the 'this' pointer, right?
So then the rule I guess is: You can't have a class containing a lambda object if that lambda object has captured the outer class (IF the outer class is movable). I think this problem extends to more general cases:
struct MoveableClass
{
struct Foo { MoveableClass* outer_class_object; };
Foo fooObj{this};
}
I can handle moving this class by using custom move functions. But in the case of std::function or if it contains a lambda, then I can't move it, right?