Как я могу заменить std :: bind на лямбду в моем коде

Учитывая следующий код:

#include <functional>
#include <iostream>

struct worker
{
   std::function<bool(std::string)> m_callback;

   void do_work(std::function<bool(std::string)> callback)
   {
      m_callback = std::bind(callback, std::placeholders::_1); // <--- replace this with lambda
      std::cout << "worker is working..." << std::endl;
      callback("worker is complete");
   }
};


// pretty boring class - a cut down of my actual class
struct helper
{
   bool work_callback(std::string str)
   {
      std::cout << "Helper: msg from worker: " << str << std::endl;
      return false;
   }
};


int main()
{
   helper the_helper;
   worker the_worker;

   std::cout << "Main: start\n";
   the_worker.do_work([&](std::string data){ return the_helper.work_callback(data); });
   std::cout << "Main: end\n\n";
}

Хочу заменить m_callback = std::bind... на лямбду. Пока у меня есть:

m_callback = [&](std::string data){ callback(data); };

Это дает мне ошибку:

main.cpp: In member function ‘void worker::do_work(std::function<bool(std::basic_string<char>)>)’:
main.cpp:19:18: error: no match for ‘operator=’ (operand types are ‘std::function)>’ and ‘worker::do_work(std::function)>)::’)
       m_callback = [&](std::string data){ callback(data); };

Я не совсем понимаю, как здесь двигаться дальше. Вы можете увидеть мою полную попытку здесь: https://onlinegdb.com/SkaADi7u7

Я не понимаю, чего вы пытаетесь достичь в worker::do_work. У вас есть параметр std::function<bool(std::string)>, и вы хотите связать аргумент ... Но затем сохраните его в другом std::function<bool(std::string)>. Здесь нет необходимости в привязке (или лямбде) - вы можете просто сделать m_callback = callback.

Max Langhof 10.09.2018 10:25

Как это: m_callback = [&](std::string const& s) { return callback(s);};coliru.stacked-crooked.com/a/bd452cc561100e2f?

user1810087 10.09.2018 10:25

Между прочим, сообщение об ошибке, которое вы получаете, искажено, потому что onlinegdb.com - это кусок дерьма с ошибками и не может должным образом HTML экранировать свои сообщения. Я рекомендую разрабатывать локально (или найти другой онлайн-компилятор).

melpomene 10.09.2018 10:35

@melpomene Ссылка, которую он опубликовал, даже не откроется для меня ...

user1810087 10.09.2018 10:39

@MaxLanghof ну, это просто глупый пример кода, который я сделал, чтобы показать проблему, с которой я столкнулся ... так что, пожалуйста, забудьте о "смысле" того, что пытаюсь достичь. Я действительно просто пытаюсь заменить код bind().

code_fodder 10.09.2018 10:39

@ user1810087 Да, он очень медленный и загружается примерно с каждой третьей попытки.

melpomene 10.09.2018 10:41

@ user1810087 ... ааа, блин, забыл вернуть!?. Спасибо :)

code_fodder 10.09.2018 10:41

@melpomene Мне пришлось скопировать это из моей защищенной сети, поэтому я использую этот онлайн-компилятор для создания своих примеров! ... знаете ли вы лучший - я согласен, что это ужасно медленно: (

code_fodder 10.09.2018 10:42

@code_fodder godbolt.org для проверки сборки и coliru.stacked-crooked.com или wandbox.org для работы.

Max Langhof 10.09.2018 10:42
ideone.com и tio.run/#cpp-gcc кажутся менее ужасными.
melpomene 10.09.2018 10:43

Попробуйте вызвать m_callback вне do_work и посмотрите, что произойдет ... (я думаю, это будет ошибка сегмента), с помощью [&] вы захватываете callback по ссылке, но это локальная переменная.

rafix07 10.09.2018 10:44

@melpomene Мне не нравится ideone.com, потому что он делает итерацию кода излишне утомительной (и тратит массу экрана на рекламу и т. д.).

Max Langhof 10.09.2018 10:45

@MaxLanghof Согласился на повторение, но рекламы я не видел.

melpomene 10.09.2018 10:45

@anyone .... почему я опускаю голоса. У меня есть минимально полный пример. У меня конкретный вопрос ... что еще? ... кроме того, что я слишком тупой? : o ... да ладно: (

code_fodder 10.09.2018 10:48

@code_fodder Я не знаю (я не отрицал этот вопрос), но ваш код далеко не минимален.

melpomene 10.09.2018 10:49

@melpomene - но ... это как два маленьких класса и main () ... Я приложил все усилия, чтобы сделать его минимальным и по-прежнему делать что-то, отражающее то, что я делаю в моем реальном коде :)

code_fodder 10.09.2018 10:55

@code_fodder Вот минимальная версия: wandbox.org/permlink/Uj4dvBe0s5N6PG4R

melpomene 10.09.2018 10:57

@melpomene, ладно, это меньше и доказывает, что ты круче, чем я! .. но на самом деле он не представляет мой код с точки зрения передачи функций-членов и того, что я пытаюсь сделать. Я мог бы сделать ваш пример еще более минимальным, удалив все пробелы / новые строки !. (Кстати, мне нравится эта коробка для палочки). Но я пытаюсь научиться составлять хороший вопрос, и с благодарностью учту ваши отзывы :)

code_fodder 10.09.2018 11:05

@code_fodder Ну, ваш вопрос на самом деле только о том, почему эта одна строка вызывает ошибку. Все остальное не имеет значения. В идеале, когда вы пытаетесь изолировать ошибку или ошибку, вы сводите ее к одному утверждению или выражению, которое не имеет смысла. Затем вы можете задать конкретный вопрос об этой части (или решить его полностью: часто действие по уменьшению проблемы помогает вам разобраться в ней самостоятельно).

melpomene 10.09.2018 11:09

@melpomene хорошо ... это имеет смысл

code_fodder 10.09.2018 11:12
1
20
2 134
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
void do_work(std::function<bool(std::string)> callback)
{
   m_callback = [&](std::string data){ callback(data); };

   std::cout << "worker is working..." << std::endl;
   callback("worker is complete");
}

Ваша лямбда вызывает функцию callback, которую вы ей передаете, но не возвращает ее результат, то есть возвращает void, и вы не можете назначить ее для std::function<bool(std::string)>.

Добавьте возврат в свою лямбду.

m_callback = [&](std::string data){ return callback(data); };

Конечно, лучше бы m_callback = std::move(callback); тоже работал.

paler123 10.09.2018 10:28

Hangon .... вы говорите, что мне даже не нужна лямбда ... надо попробовать!

code_fodder 10.09.2018 10:42

@melpomene ага .. это сработало! - Думаю, я понятия не имею, почему я использовал bind с самого начала. Пожалуйста, опубликуйте это как ответ, и я буду поддерживать его. Но этот ответ отвечает на мой конкретный вопрос, поэтому спасибо Kaldrr

code_fodder 10.09.2018 10:45

@ paler123 ... даже лучше, я думаю, тот же комментарий к вам. Хотя, если бы вы могли объяснить, почему этот шаг мне действительно помог :)

code_fodder 10.09.2018 10:47

Как сказал rafix07, вы захватываете локальную переменную (callback) по ссылке, которая остается висящей, когда возвращается do_work.

melpomene 10.09.2018 10:49

Другие вопросы по теме