
Hi Peter, --- Peter Dimov <pdimov@mmltd.net> wrote: <snip>
But the C-style facilities used in the tutorial actually do serve as a distraction to me, not just a mere annoyance.
That's fine. Don't get me wrong - I'm not arguing in favour of keeping the C-style usage. I'm just saying that I am not yet sure which of the alternative approaches is most appropriate for the tutorial. <snip>
- if the tutorial doesn't show the recommended way to use asio, what _is_ the recommended way to use it?
Why must there be the one true recommended way to use it? As far as possible I want the interface to allow alternative implementation approaches. Ideally the tutorial would introduce a few of them. My preferred approach is to use classes, binding the member functions as callbacks, and using shared_from_this() to ensure the class is kept alive as long as needed. But this may not be suited to every application. As for using this approach in the tutorial, I'm concerned that introducing shared_from_this() may be a distraction for users not already familiar with the facility.
shared_ptr<socket> is the easy part, although this immediately leads me to ask the obvious question: why isn't a socket already a shared_ptr<socket_impl>?
Why should it be? A socket has an identity and is not a value-type object. And I don't want the interface to impose the cost of using a shared pointer when it's not required. In many applications the socket object might be on the stack, or it could be a member of some other class, e.g.: class my_connection { ... asio::stream_socket socket_; ... }; where the outer class is the one that's in a shared_ptr (as it is in my preferred approach). Consider also stream layering, e.g.: asio::ssl::stream<asio::stream_socket> socket; In this case a reference counted stream_socket implementation gives no advantage - it's the entire composed stream object that would need to be reference counted. Hence the shared_ptr should be external to the stream, not internal. Perhaps the problem is that the tutorial is a little too simple, and I should find an example application that has more "real world" requirements.
For the string, my first thought was to just pass a std::string by value. This of course doesn't work because the string needs to stay alive until the operation is complete, so we need something like a shared_array<char>. I think that the library should provide one.
I don't think that this should be part of the library at this time. (Perhaps in the longer term after some patterns emerge from use - although it may be better as a separate "buffers" library.) Instead, I am tightening up the usage of the Mutable_Buffers and Const_Buffers concepts to ensure that reference counted implementations of these concepts will work correctly. Cheers, Chris