问题描述
/* 这是一个同步的echo客户端 * 在sync_echo()函数中的read函数的第三个参数中,bind有两个占位符号, * 调用read_complete()函数,可是在read_complete()函数中,需要用到bytes这个参数 * 我想请问这个bytes是怎么传进去的?*/#include <iostream>#include <boost/thread.hpp>#include <boost/bind.hpp>#include <boost/asio.hpp>#include <boost/shared_ptr.hpp>#include <boost/enable_shared_from_this.hpp>using namespace boost::asio;using boost::system::error_code;io_service service;size_t read_complete(char *buf, const error_code &err, size_t bytes){ if (err)return 0; bool found = std::find(buf, buf+bytes, ’n’) < buf + bytes; // we read one-by-one until we get to enter, no buffering return found? 0: 1;}ip::tcp::endpoint ep(ip::address::from_string('127.0.0.1'), 8001);void sync_echo(std::string msg){ msg += 'n'; ip::tcp::socket sock(service); sock.connect(ep); sock.write_some(buffer(msg)); char buf[1024]; int bytes = read(sock, buffer(buf), boost::bind(read_complete, buf, _1, _2)); std::string copy(buf, bytes - 1); msg = msg.substr(0, msg.size() - 1); std::cout << 'server echoed our ' << msg << ': '<< (copy == msg? 'OK': 'FAIL') << std::endl; sock.close();}int main(int argc, char *argv[]){ // connect several clients char *messages[] = {'John says hi', 'so does James', 'Lucy just not home', 'Boost.Asio is fun!', 0 }; boost::thread_group threads; for (char **message = messages; *message; ++ message) {threads.create_thread(boost::bind(sync_echo, *message));boost::this_thread::sleep(boost::posix_time::millisec(100)); } threads.join_all();}
问题解答
回答1:第一次看到,确实有点惊艳到。搬运,链接:http://zh.highscore.de/cpp/boost/functionobjects.html关键摘抄:_1 被称为占位符(placeholder),定义于 Boost.Bind。 除了 _1,Boost.Bind 还定义了 _2 和 _3。 通过使用这些占位符,boost::bind() 可以变为一元、二元或三元的函数。个人理解:就是说,read函数要求的第三个参数本身是个有2个参数的函数。然后针对你的问题,对于read_complete的三个参数:read函数传入的const error_code &err, size_t bytes,你传入的是buf。如果可以的话,你看read函数源码的执行流程证实一下就知道了。
回答2:问:
我想请问这个bytes是怎么传进去的?
答:在这里:int bytes = read(sock, buffer(buf), boost::bind(read_complete, buf, _1, _2));
read_complete有三个参数,bind的意思就是说,第一个参数是buf,第二个参数是返回的function的第一个参数,第三个参数是返回的function的第二个参数。如果你把_1和_2换过来,那么你在调用返回的function的时候参数也要换过来。
使用现代C++的写法如下:旧:
boost::bind(read_complete,b uf, _1, _2)
新:
[&buf](auto a, auto b){ return read_complete(buf, a, b);}