Boost logo

Boost Users :

Subject: [Boost-users] variant<T&> with throwing initialization code.
From: Zachary Turner (divisortheory_at_[hidden])
Date: 2009-07-20 17:47:29


I have a couple of variants whose inner type are all references. For example,

variant<a1&, a2&, ...> var1;
variant<b1&, b2&, ...> var2;

Because this variant will not be assignable due to the references,
they need to be initialized in a constructor initializer list.
However, it's possible for the function that creates these references
in the first place to throw, and moreover the inner types might
contain unmanaged resources that need to be properly cleaned up on a
throw. Also the construction of var_k, might depend upon the
successful construction of var_j where j<k (like for example I might
need to use some member variable in one of the previously constructed
objects to pass to one of the later objects to construct it). Is
there a decent way to handle this? The problem is that if, say,
something throws while trying to create var2, but var1 has already
been created, then var1's unmanaged resources need to be properly
freed. I tried to package all the variants together in a class such
as

typedef variant<a1&, a2&, ...> v1_type;
typedef variant<b1&, b2&, ...> v2_type;

struct package
{
   package(v1_type& v1, v2_type& v2)
      : var1_(v1), var2_(v2)
   {
   }

   v1_type var1_;
   v2_type var2_;
};

and then only have one instance of package in my class. Then, in the
initializer list call package_(create_package()), and define
create_package() as:

package create_package()
{
   optional<v1_type> v1;
   optional<v2_type> v2;
   try
   {
      v1 = create_v1();
      v2 = create_v2();

      return package(v1.get(), v2.get());
   }
   catch(...)
   {
   }
}

but for some reason this fails to compile, saying that it's trying to
call variant::operator= in the package constructor. Which doesn't
make sense since I don't think it should be.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net