
On Sun, Aug 3, 2008 at 8:15 PM, Eric Friedman <ebf@users.sourceforge.net> wrote:
Hi Emil,
On Wed, Jul 30, 2008 at 6:36 PM, Emil Dotchevski <emil@revergestudios.com>wrote:
Reading boost::variant's documentation:
"If any bounded type is nothrow default-constructible (as indicated by boost::has_nothrow_constructor), the library guarantees variant will use only single storage and in-place construction for every bounded type in the variant. Note, however, that in the event of assignment failure, an unspecified nothrow default-constructible bounded type will be default-constructed in the left-hand side operand so as to preserve the never-empty guarantee."
Do I read correctly that in an attempt to assign one variant object to another, the left-hand object _might_ silently change its type?
If an exception is thrown during assignment to a boost::variant<T0, T1, ...>, and one of the Ti is nothrow default-constructible, then the boost::variant will end up with a default-constructed value of one of those Ti. So even if the type happens already to be that Ti, the value will still change to the default value.
This makes it very difficult for the user to enforce some useful
invariants for types that have boost::variant members, which in my mind is very important.
I'd like to understand your situation better-- could you elaborate on the use case you are facing?
I have 3 variants of values, let's call them V0, V1 and V2. V0 values are of type std::string, and V1 and V2 values are of type float. However, boost::variant<std::string,float,float> is illegal; therefore I'm using: struct value_type { int variant; boost::variant<std::string,float> value; }; For value_type, I want to maintain the invariant that if variant==0, then value is of type std::string, and if variant is either 1 or 2, then value is of type float. The problem is that if std::string operator= throws, boost::variant may break value_type's invariant. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode