Re: [boost] [optional] generates unnessesary code for trivial types

I have a question though. Why prohibit opt = opt assignment? It looks quite safe and has a fairly obvious behavior. If I have an optional reference as a member of my class, the lack of assignment in optional would force me to define a custom assignment operator for my class. This seems to be an unnecessary requirement. Also, in the source code I dealt with I often saw people writing something like opt = optional<T>() to clear the value. This would break with references for no apparent reason.
First, let me show why opt = nval; is controversial. Current semantics for boost::optional<T&> is to rebind on assignment, which means that in the following code: int i = 1; int j = 2; optional<int&> oi = i; oi = j; The effect of this program is that i remains 1, j remains 2 and oi holds a reference to j. This is surprising to those that think of optional as delayed initialization. I lean towards disabling opt = opt because it is very similar to opt = nval; int i = 1; int j = 2; optional<int&> oi = i; optional<int&> oj = j; i = j; The effect here is that i remains 1, j remains 2 and oi and oj both hold a reference to j. You may find it less surprising but if you think of optional reference as a regular reference that is initialized a bit later, the behavior is not what you would expect. Note that if you store a normal reference to int as class member, you already have to write your assignment yourself. changing a normal reference to an optional reference should not come as something irregular.

On Thu, Feb 9, 2012 at 5:39 PM, Andrzej Krzemienski <akrzemi1@gmail.com> wrote:
First, let me show why opt = nval; is controversial.
I understand and agree that opt = nval may be ambiguous and even dangerous.
I lean towards disabling opt = opt because it is very similar to opt = nval;
int i = 1; int j = 2; optional<int&> oi = i; optional<int&> oj = j; i = j;
The effect here is that i remains 1, j remains 2 and oi and oj both hold a reference to j. You may find it less surprising but if you think of optional reference as a regular reference that is initialized a bit later, the behavior is not what you would expect.
I see your point but, IMHO, optional<T&> is too different from normal references to attempt to draw this association. After all, optional<T&> is an object in the sense it has internal state and you can take its address while T& is not (one may call it an alias of an object). It is therefore logical that optional<T&>::operator= operates on the object (i.e. on the optional contents) and hypothetical T&::operator= operates on the referred object.
Note that if you store a normal reference to int as class member, you already have to write your assignment yourself. changing a normal reference to an optional reference should not come as something irregular.
Again, I tend to see optional<T&> as an object, with no apparent reason why it cannot be assigned to.

int i = 1; int j = 2; optional<int&> oi = i; optional<int&> oj = j; i = j;
The effect here is that i remains 1, j remains 2 and oi and oj both hold a reference to j. You may find it less surprising but if you think of optional reference as a regular reference that is initialized a bit later, the behavior is not what you would expect.
Huh? How does oi come to hold a reference to j? Regards, Nate
participants (3)
-
Andrey Semashev
-
Andrzej Krzemienski
-
Nathan Ridge