Время жизни лямбда-захвата / объем - PullRequest
0 голосов
/ 22 апреля 2020

Рассмотрим следующий фрагмент кода (вопрос не Qt Speci c):

namespace gpds {
    class container
}

class my_widget : public QWidget
{
    Q_OBJECT
    Q_DISABLE_COPY_MOVE(my_widget)

public:
    my_widget() = default;
    virtual ~my_widget() override = default;

    [[nodiscard]] gpds::container to_container(const std::filesystem::path& base_path) const;
};

struct tool
{
    std::string name = "Unnamed Tool";
    std::shared_ptr<QWidget> widget;
    std::function<gpds::container()> to_container;
    std::function<void(const gpds::container& c)> from_container;

    tool() = default;
    tool(const tool& other) = delete;
    tool(tool&& other) = default;
    virtual ~tool() = default;
};

void foo()
{
    // Create widget
    QWidget* widget = ...;

    // Create tool
    auto tool = std::make_shared<tool>();
    tool->widget = widget;
    tool->to_container = [&widget, this]() -> gpds::container {
        std::filesystem::path project_dir = ...;
        auto w = std::dynamic_pointer_cast<my_widget>(widget);
        if (not w)
            return { };
        return w->to_container(dir);
    };

    // Do something else with the tool
    ...
}

Мой вопрос (извините за отсутствие надлежащего технического термина): захват widget в лямбда-сейфе? У меня возникли проблемы, когда my_widget::to_container() вызывается, но this имеет значение null, что приводит к ошибке сегментации. Интересно, что в лямбда-выражениях widget и правильное приведение w не равны нулю, а в my_widget::to_container() this - ноль.

Я действительно считаю, что это как-то связано с время жизни / объем лямбда-захвата widget, но я не понимаю, что искать и как добиться того, что мне нужно.

Дополнительная информация:

  • Я использую C ++ 17
  • Я убедился, что экземпляр my_widget не уничтожается до / во время вызова tool::to_container().
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...