Search code examples
c++asio

C++ Compilation error about running io_context in different thread


I am trying to use the asio::io_context in multiple threads.

#include <iostream>
#include <vector>
#include <asio.hpp>
#include <thread>
#include <future>
#include <functional>

int main()
{
    asio::io_context ctx;

    std::vector<std::future<asio::io_context::count_type>> tasks;
    for(int i = 0; i < 3; ++i)
    {
        tasks.push_back(std::async(std::launch::async, std::bind(&asio::io_context::run, &ctx));
    }

    for(auto &task: tasks){tasks.get();}
    return 0;
}

However, I am getting a compilation error

asio_blah.cpp: In function ‘int main()’:
asio_blah.cpp:101:94: error: no matching function for call to ‘bind(<unresolved overloaded function type>, asio::io_context*)’
         tasks.push_back(std::async(std::launch::async, std::bind(&asio::io_context::run, &ctx));

Not sure whey the compiler is not able to figure the member function pointer ( I believe the member func type is asio::io_context::count_type (asio::io_context*)() and the function signature should visible to the compiler since asio.hpp is included) and report the error unresolved overloaded function type.

Any suggestions to fix the error?


Solution

  • You may go for lambda something like this:

    #include <iostream>
    #include <vector>
    #include <boost/asio.hpp>
    #include <thread>
    #include <future>
    #include <functional>
    
    using namespace boost;
    
    int main()
    {
        asio::io_context ctx;
    
        std::vector<std::future<asio::io_context::count_type>> tasks;
        for(int i = 0; i < 3; ++i)
        {
            tasks.push_back(std::async(std::launch::async, [&ctx]() {
                return ctx.run();
            }));
        }
    
        for(auto &task: tasks){task.get();}
        return 0;
    }
    

    Edit:

    As rightly said by Miles Budnek, io_context::run has multiple overloads. You cannot take a pointer to it without forcing overload resolution with a cast.

    If you really want to use std::bind, go for casting.

    My opinion is same as that of others. GO FOR LAMBDA!!!