Alternative to missing method in last version of B

2020-04-19 23:20发布

Some years ago, I wrote a email client using Boost asio library.

There are a abstract class ICON with four subclasses.

POP3conN to flat POP3 communications

POP3conS to secure POP3 communications

SMTPconN to flat SMTP communications

SMTPconS to secure SMTP communications

ICON has a member

boost::asio::ip::tcp::socket socket_

and two virtual procedures, defined in echa subclass:

void SMTPconN::run() { socket_.get_io_service().run(); }
void SMTPconN::reset() { socket_.get_io_service().reset(); }

The application worked fine with boost_1_63_0. But when I try update to boost_1_70_0, the compiler (MS V Studio 2015) complains in both definitions:

class "boost::asio::ssl::stream<boost::asio::ip::tcp::socket>" has no member "get_io_service".

Because I want do the minimal change in what is a huge amount of code and complex logic: do is there some workaround to this missed method?

2条回答
Luminary・发光体
2楼-- · 2020-04-20 00:14

The docs state under Networking TS compatibility that you can use get_context().context(), which will get you a io_context instance (which replaced io_service somewhere around boost 1.64/1.65 IIRC).

Networking TS compatibility

Boost.Asio now provides the interfaces and functionality specified by the "C++ Extensions for Networking" Technical Specification. In addition to access via the usual Boost.Asio header files, this functionality may be accessed through special headers that correspond to the header files defined in the TS. These are listed in the table below:

[...]

Use get_executor().context() to obtain the associated io_context.

Both get_io_service() and get_io_context() were previously in place to facilitate porting, but they have in the mean time also been deprecated and obsoleted.

PS: Also see Get boost::asio::io_context from a boost::asio::ip::tcp::socket to exec a custom function which is eerily similar to your question but specifies a specific use-case.

The comments there have the decidedly better solution for that use-case:

socket.get_io_service().post([](){ /* my custom code */ } );

Becomes

post(socket.executor(), [](){ /* my custom code */ } );
查看更多
够拽才男人
3楼-- · 2020-04-20 00:19

The subclasses: POP3conN and SMTPconN have a member:

boost::asio::ip::tcp::socket socket_

Similarly, POP3conS and SMTPconS have a member:

boost::asio::ssl::stream<boost::asio::ip::tcp::socket>  socket_;

The first argument of all constructors is a pointer to io_service. Some like:

IPCON::IPCON(boost::asio::io_service* ioserv_, ...) { ... }

POP3conN::POP3conN(boost::asio::io_service* ioserv_, ....) {...}

First change: in the abstract class IPCON has been added a new member:

boost::asio::io_context* iocontPtr_;

wich is initialized in the constructor replacing the old reference to io_service:

IPCON::IPCON(boost::asio::io_context* iocont_, ...) { ... }

In the constructors of the subclasses has been added initialization to such member:

POP3conN::POP3conN(boost::asio::io_context* iocont, ....) : IPCON(iocont) { ... }

Second change: all occurences of

boost::asio::io_service

Can be replaced by

boost::asio::io_context

The problematic expressions

void SMTPconN::run() { socket_.get_io_service().run(); }
void SMTPconN::reset() { socket_.get_io_service().reset(); }

appears now like this:

void SMTPconN::run() { iocontPtr->run(); }
void SMTPconN::reset() { iocontPtr->reset(); }

It seems that the functionality of the old io_service has been replaced by the new io_context.

查看更多
登录 后发表回答