From: Eric Friedman (ebf_at_[hidden])
Date: 2003-10-10 20:01:36
I'd like to direct the recent discussion on variant toward a conclusion.
I think it is very important to decide how a variant should behave in
general after a failed assignment. There are two options: 1) the variant
contains an initialized value of one of its bounded types; or 2) the
variant is singular. (For reference, I provide a summary of the
semantics and efficiency of these two options at the end of my message.)
The question that needs to be answered is the following:
"Is a singular variant worse than one with unspecified content?"
To explain, I suggest the following example:
void f(variant< T1,T2 > & v)
v = g();
Assume that upon entering f, v contains value of type T1. Assume further
that the assignment v = g() fails with an exception.
For the caller of f, and for any other part of the program that may
contain a pointer or reference to v: is error-recovery possible if v
contains an unknown value of either type T1 or T2 (i.e., variant
implements option 1)?
Since the value of v is in general wholly unspecified, it seems to me
that the only way to ensure meaningful content for v is another
assignment. This suggests to me that a singular variant is no worse than
one with unspecified content.
Am I overlooking something?
--- Option 1. With this option, the variant continues to contain an initialized value of one of its bounded types, but it does not guarantee any particular content value or type. In terms of implementation, this requires that some sort of fallback strategy be available for variant in the event of an exception. If one of variant's bounded types is nothrow default-constructible, then construction of such a type constitutes an appropriate fallback strategy. In the general case, however, the fallback strategy must rely on either double storage within the variant or temporary backup on the heap. [Currently, variant implements this option, using heap backup as its general fallback strategy.] Option 2. With this option, the variant does not contain any value, and the result of most operations on the variant are undefined. The only defined operation is assignment of a nonsingular variant to the singular variant. (These semantics mirror the STL's concept of singular iterators; see http://www.sgi.com/tech/stl/trivial.html.) In terms of implementation, this requires a simple check in variant's destructor to handle the special case of a singular variant. Neither heap backup nor double storage is necessary.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk