
Christopher Kohlhoff wrote: [...]
Basically I would add a new static function basic_demuxer<>::global(), which returns a reference to the singleton demuxer object. Constructors would look something like:
basic_stream_socket(demuxer_type& d = demuxer_type::global())
Synchronous-only code could then be written without knowledge of the demuxer:
ipv4::host_resolver r; stream_socket s; deadline_timer t; etc...
However, unlike Jeremy's dummy demuxer suggestion, the async operations would still be allowed.
[...]
I generally dislike singletons because of the issues to do with the order of cosntruction and cleanup.
You should dislike singletons because they are global variables. The problem with the above apporach is that most code will end up using the global demuxer because this is the path of least resistance. When it turns out that the code needs to be refactored to use a specific demuxer, the programmers would need to go over it with a fine-toothed comb and replace every implicit reference to the global demuxer with an explicit demuxer reference, passing that reference wherever necessary. It'd be a pain, and it'd be easy to miss some. Not to mention that the code that implicitly uses the global demuxer may be in a library for which the source is not available. So yes, the easy case will be easier, but the hard case will be harder.