这是一个基于boost asio example的boost :: asio udp echo demo。
使用C ++ lambda的这个版本的内容不到提升示例的一半,但是gcc告诉我received
中recv_from
不可见。
我不得不以更冗长的方式写这篇文章。一些C ++专家可以帮助我定义相互递归的lambdas吗?
class server {
public:
server(io_service& io_service, short port)
: socket_(io_service, udp::endpoint(udp::v4(), port)) {
auto recv_from = [&,received]() {
socket_.async_receive_from(buffer(data_, max_length), sender_endpoint_,
received);
};
auto received = [&,recv_from](const error_code& error, size_t bytes_transferred) {
if (!error && bytes_transferred > 0) {
socket_.async_send_to(buffer(data_, bytes_transferred), sender_endpoint_,
[&](const error_code&, size_t) {
recv_from();
});
} else {
recv_from(); // loop
}
};
recv_from();
}
private:
udp::socket socket_;
udp::endpoint sender_endpoint_;
enum { max_length = 1024 };
char data_[max_length];
};
编辑,解决方案:我需要添加:
std::function<void(const error_code&, size_t)> received;
使类型推理引擎变得容易(我已经编程了Haskell)
Edit2:存在生命周期问题,因此无效。
答案 0 :(得分:4)
回答我自己的问题:
我的代码实际上至少有三个问题。
我一直小心地将<{>> received
和recv_from
复制到相应的闭包中,以便在构造函数超出范围时它们可用。
不幸的是,闭包go out of scope与构造函数同时出现。因此[&, xxx]
xxx
的复制毫无意义。
必须修改至少(?)其中一个lambda的类型以取悦类型推理引擎。
但这并不能解决问题#1。为了解决生命周期问题,我应该将闭包对象存储在server
对象中。
所以我认为这接近我需要做的事情:
class server {
public:
server(io_service& io_service, short port)
: socket_(io_service, udp::endpoint(udp::v4(), port)) {
recv_from = [&]() {
socket_.async_receive_from(buffer(data_, max_length), sender_endpoint_,
received);
};
received = [&](const error_code& error, size_t bytes_transferred) {
if (!error && bytes_transferred > 0) {
socket_.async_send_to(buffer(data_, bytes_transferred), sender_endpoint_,
[&](const error_code&, size_t) {
recv_from();
});
} else {
recv_from(); // loop
}
};
recv_from();
}
private:
udp::socket socket_;
udp::endpoint sender_endpoint_;
std::function<void(const error_code&, size_t)> received;
std::function<void()> recv_from;
enum { max_length = 1024 };
char data_[max_length];
};