C когда я пытаюсь получить строку, она всегда пуста, лямбда

#c #lambda #g

#c #лямбда #g

Вопрос:

У меня есть объект класса

 class MenuItem {
public:
    void updateInputText(string text)
    {
        this->text  = text;
    }

    string getText() const {
        return this->text;
    }

    void trigger(Event event)
    {
        switch (event) {
            case ENTER:
                this->onEnterAction();
                break;
        }
    }

    function<void(void)> onEnterAction;

private:
    Text text;
    void onEnter();
};
 

Я создаю объект и устанавливаю обработчик событий

 MenuItem IP;
IP.onEnterAction = eventOnEnter;
// ENTER - element from enum
IP.trigger(ENTER);
 

Обработчик событий:

 function<void(void)> eventOnEnter = [amp;] () {
    auto selected = next(this->currentMenu.begin(), this->selected);
    selected->updateInputText("Hello");
};
 

И второй объект MenuItem

 MenuItem nextButton;
next.onEnterAction = [amp;] () {
    Log::write("IP: "   IP.getText());
};
// ENTER - element from enum
next.trigger(ENTER);
 

Но IP.getText() всегда пуст. Что я делаю не так?

Все объекты, созданные в одной области (в одной функции)

Комментарии:

1. в опубликованном вами коде нет очевидной проблемы, хотя вы не вызываете ни один из двух лямбд, поэтому text он не изменен в опубликованном вами коде

Ответ №1:

Всякий раз, когда я вижу что-то подобное

 MenuItem nextButton;
next.onEnterAction = [amp;] () { // Should next be nextButton???
    Log::write("IP: "   IP.getText());
};
// ENTER - element from enum
next.trigger(ENTER);
 

Я жду, когда произойдет катастрофа. И если бы вы показали полностью рабочий пример, вы бы отметили, что ваш пример кода мог бы сработать… итак, в чем проблема.

Основная проблема в том, что вы фиксируете все по ссылке, но из вашего кода я не могу понять, должно ли это работать, но я думаю, что не в большой системе, причина в том, что захваченные значения вышли за рамки.

 std::vector<MenuItem> CreateMenu() {
  std::vector<MenuItem> res;
  function<void(void)> eventOnEnter = [amp;] () {
    auto selected = next(this->currentMenu.begin(), this->selected);
    selected->updateInputText("Hello");
  };
  
  MenuItem IP;
  IP.onEnterAction = eventOnEnter;
  res.push_back(IP);
  

  MenuItem nextButton;
  nextButton.onEnterAction = [amp;] () {
    Log::write("IP: "   IP.getText());
  };
  res.push_back(nextButton);

  return res;
}

void Call() {
  auto buttons = CreateMenu();
  // what is captured at this point???  
  buttons.back().trigger(ENTER);
}
 

Большая часть захваченного теперь вышла из области видимости.

Ответ №2:

Сурт дал мне подсказку… Область видимости.

Все элементы меню перемещаются в вектор, и когда я использую эту функцию

 next.onEnterAction = [amp;] () {
    Log::write("IP: "   IP.getText());
};
 

Я пытаюсь получить текст из пустой переменной, когда я изменил функцию на

 next.onEnterAction = [amp;] () {
    auto selectedIP = std::next(currentMenu.begin(), 0);
    Log::write("IP: "   selectedIP.getText());
};