
On Wed, 31 Aug 2011 01:07:36 -0700, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
On Tue, Aug 30, 2011 at 10:23 PM, Mostafa <mostafa_working_away@yahoo.com>wrote:
Boost.Optional seems to really have a lot of potential for what I want to do, but one thing about it has been nagging me, specifically it's assignment semantics for wrapped references being different from the semantics of bare C++ references (see http://tinyurl.com/4yna643).
So...you don't agree with the rationale?
I don't believe I wrote anything to imply that. I had a hard time following the rationale, so I've taken the author(s) at their word.
Has/have the author(s) of the library or anyone considered disallowing assignment for Boost.Optional types that wrap references, and if so, what would the consequences of this entail? I rather disallow assignment in this case, then have what's basically a wrapper class behave partially differently than the type it's supposed to emulate.
Given that there's an entire section of the documentation devoted to the semantics of assignment, I'd infer the author(s) consider the various possibilities for assignment, including disallowing it.
They may have considered disallowing it, but there's no mention of that consideration in the document, nor, assuming that they did consider such a possibility, why they rejected it.
If you disallowed assignment for optional<T&>, then surely you would likewise need to disallow default constructability, and then how would an optional<T&> really be any different from a T& other than the syntactic clutter?
Sorry, I don't follow you here. A defaulty constructed "optional<T&> pp;" would convey that someone has decided not to set the value of pp, exactly because the type of pp is *optional*<T&>. Hence, optional<T&> conveys more information than T&.
Perhaps you can elaborate on why the current assignment semantics are troubling to you...?
Let me reword and expand my concerns. I view boost::optional as a thin wrapper for it's underlying type, with the added sugar that it can convey whether its instance has or has not been set by the user. Hence, it behaves very much like a smart pointer. I expect pointer semantics to be a subset of smart pointer semantics, ie, whatever operations I can perform on pointers, I too can perform on smart pointers (where they are allowed) and get the same results. So for example, *p and p-> will give the same results regardless of whether p is a plain old pointer or a smart pointer. Where p is a smart pointer and "p + 5" is disallowed then I just say bummer, and do "p.get() + 5"; however, where "p + 5" was allowed and it behaved differently than "p.get() + 5", then I would be unpleasantly shocked, no matter how in-your-face it may have been blared in the documentation. In large software projects, heck, even in medium-sized teams, not everyone will read the *whole* documentation, they'll just glance enough at it to figure out how to solve their immediate need. With respect to the documentation for Boost.Optional, yes, there is a whole section on option<T&> assignment, but it in no way stands out from the rest of the documentation, and even within the said section, the only clue as to why it's there in the first place is a bold "rebind" which automatically catches my eye, but no red flags, no caution sign, nothing else. But my beef isn't with the documentation, as I said, even if it was blaring with a flashing red sign, I still would be hesitant because *not everyone reads the whole documentation*, for good or bad. Hence my desire to disallow inconsistent behaviour with regards to existing convention. More specifically, and to answer your question, what bugs me is that the semantics of the operations that I can perform on T& are not a subset of the semantics of the same operations that I can perform on optional<T&>, per the documentation: "Now, if you assign to an initialized optional<T&>, the effect is to rebind to the new object instead of assigning the referee. This is unlike bare C++ references." The rationale for such a rebinding of optional<T&> maybe very sound, and rebinding maybe the only choice to achieve consistent behaviour with respect to Boost.Optional, but it doesn't negate the fact that the semantics of the assignment operation that I perform on T& are not a subset of the semantics of the same operation that I perform on optional<T&>. And given the near universal rule that not all programmers read the whole documentation, there will inevitably come along some programmer who will assume that optional<T&> behaves at least like T& wherever the operations are defined on both (and rightly so in my opinion), and in the course of doing some maintenance on some large code base, the said programmer will introduce a bug that maybe easy to detect but will be hard to diagnose because of the need to reread the documentation. Hence my desire to explore the consequences of disallowing the assignment operation for optional<T&> and the reason for starting this thread. Hopefully this explains things better, Mostafa