见:http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/examples/cpp11_examples.html
或者https://github.com/NearXdu/AsioLearn
代码中有一些内容值得学习。
1.lambda表达式
可调用对象的一种表达方式,以前我们熟知的两种可调用对象,一个是函数、一个是函数指针。
lambda表达式的形式如下:
[capture list](parameter list)-> return type{function body}
在我的理解来看,lambda表示是函数指针的一种表示,比如说:
stable_sort(words.begin(),words.end(),
[](const string &a,const string &b)
{
return a.size()<b.size();
});
当stable_sort
比较两个元素时将调用lambda表达式。
asio的example中,也使用了lambda表达式,可以用来替代传统(C++03版本)的boost::bind()
acceptor_.async_accept(socket_,
[this](boost::system::error_code ec)//lambda
{
if(!ec)
{
//std::move
auto ptr_= std::make_shared<session>(std::move(socket_));//shared_ptr
weakPtr=ptr_;
ptr_->start();
}
do_accept();
});
在这段代码中,使用了lambda表达式,替代了boost::bind()
或者函数指针,同样的代码可以看看C++03的版本:
session_ptr new_session(new session(io_service_));
acceptor_.async_accept(new_session->socket(),
boost::bind(&server::handle_accept, this, new_session,
boost::asio::placeholders::error));//这里使用boost::bind将参数绑定到类成员函数中。
2.仿函数和模板
接下来这段操作就厉害了,先看代码:
template <typename Handler>
class custom_alloc_handler
{
public:
custom_alloc_handler(handler_allocator& a, Handler h)
: allocator_(a),
handler_(h)
{
}
#if 1
template <typename ...Args>
void operator()(Args&&... args)
{
handler_(std::forward<Args>(args)...);//调用handler
}
#endif
//...
};
template <typename Handler>
inline custom_alloc_handler<Handler> make_custom_alloc_handler(
handler_allocator& a, Handler h)
{
return custom_alloc_handler<Handler>(a, h);
}
void do_read()
{
auto self(shared_from_this());
/*
*void async_read_some(
*const MutableBufferSequence & buffers,
*ReadHandler handler);
*/
#if 1
auto handler=make_custom_alloc_handler(allocator_,
[this,self](boost::system::error_code ec,std::size_t length)
{
if(!ec)
{
std::cout<<"read: "<<length<<"bytes"<<std::endl;
do_read();
}
});
#endif
socket_.async_read_some(boost::asio::buffer(data_),
handler);
}
上述代码中,通过make_custome_alloc_handler返回一个custom_alloc_handler仿函数对象,并且在重载的operator()中,调用handler,我仔细研究了一下这段代码,的确很厉害。
关于functor的一个例子,参考:
#include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp>
using namespace std;
typedef boost::function<void(int,int)>handler;
class functor
{
public:
void operator()(int a,int b)
{
cout<<a<<b<<endl;
cout <<"hello world"<<endl;
}
};
int main()
{
handler handler_=functor();
auto tmp = boost::bind(handler_,_1,3);
tmp(1);
//输出1,3
//hello world
return 0;
}