4

This works well:

class cStartSequence
{
void Tick()
{
// do something
}
void Wait()
{    
    myTimer->expires_from_now( 
        boost::posix_time::seconds( mySecs ) );
    myTimer->async_wait(boost::bind(
                            &cStartSequence::Tick,
                            this
                               ));
}
 ...
};

I want to be able to cancel the timer and have the handler do something different

void Tick( boost::system::error_code & ec )
{
  if( ! ec )
     // do something
  else
    // do something different
}

The question is how to modify the call to async_wait?

This does not compile

myTimer->async_wait(boost::bind(
                        &cStartSequence::Tick,
                        this,
                        boost::asio::placeholders::error
                         ));

compiler complaint:

C:\Users\James\code\boost\v1_63\boost\bind\bind.hpp|319|error:
  no match for call to 
  '(boost::_mfi::mf1<void, pinmed::wrs::cStartSequence, boost::system::error_code&>) 
 (pinmed::wrs::cStartSequence*&, const boost::system::error_code&)'

I tried some variations on the async_wait parameters, but no luck.

boost:asio v1.63, windows 10, code::blocks v16.01

sehe
  • 374,641
  • 47
  • 450
  • 633
ravenspoint
  • 19,093
  • 6
  • 57
  • 103

1 Answers1

2

Your Tick method takes a non-const reference. That's not ok (and doesn't satisfy the handler requirements). Use either

void Tick(boost::system::error_code const& ec);

Or maybe

void Tick(boost::system::error_code ec);

The first one is preferred by Asio author(s) for slightly obscurantist reasons (library-specific optimizations IIRC)

PS. For safe cancellation of deadline timers see also

sehe
  • 374,641
  • 47
  • 450
  • 633
  • Using const wherever possible is a neat concept. In practice, the compiler error messages are so vague that I must have wasted hours over the years staring at errors like this. Why wont compilers come right out and tell us to look at problems with const! – ravenspoint Nov 27 '17 at 20:23
  • It's not a matter of "throwing const in everywhere". (It makes a lot of sense to not expect a mutable lvalue reference by the way). Also, it should already point you at the static_assert in default configuration: [static assertion failed: WaitHandler type requirements not met](http://coliru.stacked-crooked.com/a/f3fcd416506f8e53). In the case of `bind` you don't get that, but it says [`error: binding reference of type 'boost::system::error_code&' to 'const boost::system::error_code' discards qualifiers`](http://coliru.stacked-crooked.com/a/3e18ed6eba0e9bdc). I suggest to avoid `bind()` – sehe Nov 27 '17 at 20:30
  • You obviously speak compilerese much more fluently that I ever will. I still think compile error messages could and should be much clearer when this sort of thing happens. Avoiding bind?!?! Probably the method I user more than any other. – ravenspoint Nov 27 '17 at 20:44
  • Why? Don't you have c++11? Depending on where you mismatched the types, it even works better: [without const (static assertion)](http://coliru.stacked-crooked.com/a/147f730dbd282e02) or [with const](http://coliru.stacked-crooked.com/a/63d34b1be21bfdee). If you don't want to need to be so fluent, avoid bind. It hides the real stuff in complicated machinery that just slows compilation down and doesn't add much (if anything) – sehe Nov 27 '17 at 20:56
  • No need to change all existing code (assuming it works). – sehe Nov 27 '17 at 20:57
  • This is likely not the place, but I would be interested to know how bind can be "avoided". AFAIK it is the only way to call a class member function as an event handler. http://www.boost.org/doc/libs/1_65_1/doc/html/boost_asio/tutorial/tuttimer4.html – ravenspoint Nov 27 '17 at 21:02
  • It maybe the right place, but no longer the right time. Look up, 7 minutes ago – sehe Nov 27 '17 at 21:04