
Rob Stewart wrote:
As I understand it, the operation is inherently unsafe; it isn't a matter of efficiency, or even desirable usage. Given that, it is most appropriate that you spell things differently. You want to call attention to such usage.
Even though the usage is undesirable, it may still be necessary in cases where the singleton needs to behave polymorphically like one of its base classes.
Having said that, is it really the case that operator *() couldn't do the same work as operator ->() (possibly adding an exception if you can't get the underlying object)?
The difference is that the pointer returned by operator -> is guaranteed to be used immediately, and by using an intermediate pointer class I can construct a lock for the duration of the member call (this technique is described in Modern C++ Design, in the smart pointer section). Operator * is incapable of constructing this type of temporary lock, and additionally there is no guarantee that the reference returned would used and discarded immediately. Once the actual reference is returned, no more checking can take place.
Assuming you still don't provide operator *(), or you also want the raw semantics of your get_unsafe_*() function(s), I wonder if cast notation wouldn't be even better (versus providing access as a public member function):
T * q(unsafe<T *>(p)); T & r(unsafe<T &>(p));
That is, unsafe() (whatever you might call it) would always take a singleton pointer, but depending upon whether it was parameterized to get a pointer or reference would do something different.
I do like that syntax. Thanks for the suggestion, I'll see if I can make that work. -Jason