Home > other >  Not able to compile some shared code using boost::asio sockets in both boost v1.69 and v1.71
Not able to compile some shared code using boost::asio sockets in both boost v1.69 and v1.71

Time:08-30

I have to maintain two different legacy projects with some shared source code, one of them is tied to boost v1.69 and the other one is tied to boost v1.71.

The problem here is that compiler is working with v1.71 and failing with v1.69 when using some boost::asio sockets class.

The other restriction is to use c 17 or earlier, so sadly c 20 fancy features are not allowed here.

Here is a minimal (really minimal) functional example, just to show the problem. Do not expect this sample code doing anything, not even trying to connect.

Godbolt link: https://godbolt.org/z/fj4E8qhxT

#include <map>
#include <boost/asio.hpp>

namespace tcpsocket
{

using boost::asio::ip::tcp;

class client
{
public:
    client(boost::asio::executor executor) : socket(executor) {}

private: 
    tcp::socket socket;
};

}//namespace tcpsocket

int main()
{
    boost::asio::io_context ioc;
    std::map<int, tcpsocket::client> clients;
    
    //This is working with boost v1.71 but failing with boost v1.69
    auto id{125};
    auto[it, ok] = clients.emplace(id, ioc.get_executor());
    if (ok)
        auto& client = it->second;
}

Is it using a boost::asio::io_context& (watch the reference &) a very naive solution solution to solve this problem? I mean, was there any hidden problem with that in a single threaded application?

Well, there is at least one problem, the change from get_io_context() to get_executor() between versions.

Any help with this?

CodePudding user response:

pre-1.70.0 Asio doesn't support executors in IO objects yet: Changelog

  • Added custom I/O executor support to I/O objects.

    • All I/O objects now have an additional Executor template parameter. This template parameter defaults to the asio::executor type (the polymorphic executor wrapper) but can be used to specify a user-defined executor type.

    • I/O objects' constructors and functions that previously took an asio::io_context& now accept either an Executor or a reference to a concrete ExecutionContext (such as asio::io_context or asio::thread_pool).

I'd go with the old interface:

Live On Compiler Explorer

#include <map>
#include <boost/asio/version.hpp>
#include <boost/asio.hpp>
#include <iostream>

namespace tcpsocket
{

using boost::asio::ip::tcp;
using boost::asio::io_context;

class client
{
public:
    client(io_context& ctx) : socket(ctx) {}

private: 
    tcp::socket socket;
};

}//namespace tcpsocket

int main()
{
    std::cout << BOOST_ASIO_VERSION << " " << BOOST_VERSION << "\n";
    boost::asio::io_context ioc;
    std::map<int, tcpsocket::client> clients;
    
    //This is working with boost v1.71 but failing with boost v1.69
    auto id{125};
    auto[it, ok] = clients.emplace(id, ioc);
    if (ok)
        auto& client = it->second;
}

Prints either

101202 106900

or

101401 107100
  • Related