mercredi 19 septembre 2018

param of asio timer async_wait difference `lambda`, `bind`, `function pointer`

When I use boost::asio::steady_timer, I find something difference between lambda, bind, function pointer.

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

void print() { std::cout << "Hello, world!" << std::endl; }

int main()
{
    boost::asio::io_context io;

    boost::asio::steady_timer t(io, boost::asio::chrono::seconds(5));
    t.async_wait(&print); // Error
    t.async_wait([]{print();}) // Error
    t.async_wait(std::bind(print)); // Done

    io.run();

    return 0;
}

I read asio manual, async_wait handler need const boost::system::error_code& error param. So if I changed print to void print(const boost::system::error_code & /*e*/), all things was right. But asio example of timer4/timer.cc && timeouts/server.cc used handler creating by bind without void print(const boost::system::error_code & /*e*/). When I changed to lambda, compile was wrong. So, what difference of signature been had between bind && lambda.

#include <iostream>
#include <functional>
#include <boost/asio.hpp>
#include <boost/bind.hpp>

class printer
{
public:
    printer(boost::asio::io_context &io)
        : timer_(io, boost::asio::chrono::seconds(1)), count_(0)
    {
        timer_.async_wait(std::bind(&printer::print, this));
    }

    ~printer() { std::cout << "Final count is " << count_ << std::endl; }

    void print()
    {
        if (count_ < 5) {
            std::cout << count_ << std::endl;
            ++count_;

            timer_.expires_at(timer_.expiry() +
                      boost::asio::chrono::seconds(1));
            timer_.async_wait(boost::bind(&printer::print, this));
            // timer_.async_wait([this]{print();}); Error
        }
    }

private:
    boost::asio::steady_timer timer_;
    int count_;
};

int main()
{
    boost::asio::io_context io;
    printer p(io);
    io.run();

    return 0;
}

Aucun commentaire:

Enregistrer un commentaire