
2010/12/9 Hicham Mouline <hicham@mouline.org>
struct S { virtual ~S() {} }; struct Deriv1 : public S { virtual ~Deriv1() {} }; struct Deriv2 : public S { virtual ~Deriv2() {} }; struct Deriv3 : public Deriv2 { virtual ~Deriv3() {} };
typedef boost::variant<S,Deriv1, Deriv2, Deriv3> my_variant_t; typedef boost::mpl::sort<my_variant_t::types, boost::mpl::not_<boost::is_base_and_derived<boost::mpl::_,boost::mpl::_> >
::type v0_sorted_t;
template <typename Variant, typename Base> struct assign { assign(Variant& v, const Base& b) : v_(v), assigned_(false), b_(b) {}
template <typename T> void operator()(const T&) { std::cout<< typeid(T).name() <<std::endl; if (!assigned_) { const T* t = dynamic_cast<const T*>(&b_); if (t!=0) { v_ = (*t); assigned_ = true; } } } private: Variant& v_; bool assigned_; const Base& b_; };
int main() { S s; Deriv1 d1; Deriv2 d2; Deriv3 d3;
const S& base = s;
my_variant_t vvv; boost::mpl::for_each<v0_sorted_t>( assign<my_variant_t,S>(vvv, base) );
std::cout<< vvv.which() <<std::endl; return 0; }
A thought: won't the following minor design change simplify things? I think You can avoid sorting the types by introducing struct Deriv0 : S to be used wherever objects of class S were used. While You're at it, You can make S an abstract base ;-) Regards, Kris