C++ 11.Lambdas成员变量捕获,"这个"指针陷入STL列表中

TSB*_*99X 3 c++ lambda stl c++11

我有一个带简单按钮的简单事件系统.该系统由std :: function列表驱动,内部分配了lambdas.

这是完整的按钮类:

class Button {

private:

    Square square;
    Text label;
    bool hovered = false;
    std::function <void ()> on_mouse_enter;
    std::function <void ()> on_mouse_leave;

public:

    Button (const Square& SQUARE, const Text& LABEL):
        square {SQUARE},
        label {LABEL}
    {
        on_mouse_enter = [this] () {
            square.set_color(1, 1, 1);
        };

        on_mouse_leave = [this] () {
            square.set_color(0, 0, 0);
        };
    }

    std::function <void (const Render&)> get_rendering() {
        return [this] (const Render& RENDER) {
            RENDER.draw(square);
            RENDER.draw(label);
        };
    }

    std::function <void (const Point&)> get_updating() {
        return [this] (const Point& CURSOR) {
            if (not hovered) {
                if (is_including(square, CURSOR)) {
                   hovered = true;
                   if (on_mouse_enter)
                       on_mouse_enter();
                }
            } else
                if (not is_including(square, CURSOR)) {
                   hovered = false;
                   if (on_mouse_leave)
                       on_mouse_leave();
                }
        };
    }

};
Run Code Online (Sandbox Code Playgroud)

我将这样的按钮添加到事件管理器,如下所示:

Button button {/*SOME_PARAMS_HERE*/};

mngr.push_to_render(button.get_render());
mngr.push_to_updater(button.get_updater());
Run Code Online (Sandbox Code Playgroud)

它完美无缺,on_mouse_enteron_mouse_leave按预期工作.

但是,如果我使用STL容器包装器执行某些操作,请执行以下操作:

std::list <Button> sb;

sb.emplace_back(Button {/*SOME_PARAMS_HERE*/});

mngr.push_to_render(sb.back().get_render());
mngr.push_to_updater(sb.back().get_updater());
Run Code Online (Sandbox Code Playgroud)

整件事情正在崩溃.on_mouse_enteron_mouse_leave没有按预期工作.

随着输出调试消息,我可以看到,广场,访问这个on_mouse_enteron_mouse_leave是他们不应该是正方形,然后我看到,是不是它应该是.

这种捕获有什么问题以及如何解决?

Yak*_*ont 5

this如果要复制,请不要捕获.无论你捕获什么,你都负责管理生命.

其次,指向传递给进入/离开的按钮的指针很有意义.

std::function<void(Button*)> on_mouse_enter;
std::function<void(Button*)> on_mouse_leave;
Run Code Online (Sandbox Code Playgroud)

然后我们有:

    on_mouse_enter = [] (Button* but) {
        but->square.set_color(1, 1, 1);
    };

    on_mouse_leave = [] (Button* but) {
        but->square.set_color(0, 0, 0);
    };
Run Code Online (Sandbox Code Playgroud)

并且复制构造函数不再为您指向不同的指针this.

最后,当你打电话时on_mouse_enter,通过this.