我正在同时学习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
变量超出了作用域,lambda的callback
变量成为了悬空引用,它是对构造函数的callback
变量的引用。因此,我修改了关键行:
callback = [callback, &](const boost::system::error_code&) { // critical line
然后编译它,运行它,却得到了一个坏的函数调用错误。我理解为什么会出现这个错误。在lambda的作用域内,构造函数的
callback
变量仍然没有被赋值,因此实际上它是一个悬空函数指针。因此,lambda的callback
变量(构造函数的callback
变量的副本)也是一个悬空的函数指针。
思考了一段时间后,我意识到我真正需要的是回调能够使用函数指针引用自身,而不是引用函数指针的引用。该示例通过使用命名函数作为回调来实现了这一点,而不是使用匿名函数。但是,将命名函数作为回调传递并不是非常优雅。有没有办法让匿名函数拥有一个指向自身的函数指针作为局部变量?