
On Wed, Dec 26, 2018, 06:13 Vinnie Falco via Boost <boost@lists.boost.org wrote:
On Tue, Dec 25, 2018 at 4:54 AM Antony Polukhin via Boost <boost@lists.boost.org> wrote:
Hmmm... just double checking that my knowledge is up to date: there's no way to create a timer, async wait for it and pass the ownership to the callback. In other words, code like the following can not be improved in C++14:
The version of C++ has nothing to do with what is possible or how the asynchronous ownership model works. I/O objects need a stable address. After an asynchronous operation completes, it is likely that the operation will be repeated in the future. For example, you will likely read from a socket again. Therefore, your "operation" for delaying the execution of a single function object might look like this:
class delayed_runner { net::steady_timer tm_;
public: using clock_type = std::steady_clock; ... template <class NullaryFunction> NET_INITFN_RESULT_TYPE(NullaryFunction, void(void)) async_run_after (clock_type::duration expiry_time, NullaryFunction&&);
template <class NullaryFunction> NET_INITFN_RESULT_TYPE(NullaryFunction, void(void)) async_run_at (clock_type::time_point expiry_time, NullaryFunction&&);
void cancel(); };
The caller is responsible for ensuring this object is not destroyed while there is an outstanding operation. Similar to how a socket is treated, a `delayed_runner` would be a data member of some "session" object which is itself managed by `shared_ptr`. Completion handlers use a "handler owns I/O object" shared ownership model, so the function object contains a bound copy of the shared pointer, ensuring that the lifetime of the I/O object extends until the function object is invoked or destroyed.
Yes, thank you, I knew that. The statement was that the ASIO classes should be stored by value. I was wondering about the possibility of that in some cases. The version of the C++ Standard is relevant here. C++17 added guaranteed copy elisions and brought more order into evaluation order :) Does it allow to make a callback with stable address and an async waiting timer in it without a call to operator new?