Я учусь boost :: asio и C ++ 11 одновременно.Одна из моих тестовых программ, которая на самом деле является адаптацией одного из примеров, приведенных в учебнике boost :: asio , выглядит следующим образом:
#include <iostream>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
class printer {
// Static data members
private:
const static boost::posix_time::seconds one_second;
// Instance data members
private:
boost::asio::deadline_timer timer;
int count;
// Public members
public:
printer(boost::asio::io_service& io)
: timer(io, one_second), count(0) {
std::function<void(const boost::system::error_code&)> callback;
callback = [&](const boost::system::error_code&) { // critical line
if (count < 5) {
std::cout << "Current count is " << count++ << std::endl;
timer.expires_at(timer.expires_at() + one_second);
timer.async_wait(callback);
}
};
timer.async_wait(callback);
}
~printer() {
std::cout << "Final count is " << count << std::endl;
}
};
const boost::posix_time::seconds printer::one_second(1);
int main() {
boost::asio::io_service io;
printer p(io);
io.run();
return 0;
}
Когда я запускаю эту программу, яполучить ошибку сегментации.Я понимаю, почему я получаю ошибку сегментации.После завершения работы конструктора переменная callback
конструктора выходит из области видимости, а переменная callback
лямбда-выражения, которая является ссылкой на переменную callback
конструктора, становится висячей ссылкой.
ИтакЯ изменяю критическую строку следующим образом:
callback = [callback, &](const boost::system::error_code&) { // critical line
Затем скомпилирую ее, запустлю и получу ошибку вызова функции.Опять же, я понимаю, почему я получаю ошибку вызова функции.В области видимости лямбды переменной callback
конструктора до сих пор не было присвоено никакого значения, поэтому она для всех практических целей представляет собой висячий указатель на функцию.Следовательно, переменная callback
лямбды, которая является копией переменной callback
конструктора, также является указателем на висячую функцию.
Подумав некоторое время над этой проблемой, я понял, чтоМне действительно нужно, чтобы обратный вызов мог ссылаться на себя , используя указатель на функцию, а не ссылку на указатель на функцию .Пример достиг этого, используя именованную функцию в качестве обратного вызова вместо анонимной.Однако передача именованных функций в качестве обратных вызовов не очень элегантна.Есть ли способ получить анонимную функцию с указателем на себя в качестве локальной переменной?