|
Boost Users : |
Subject: Re: [Boost-users] variant over base and derived classes
From: Hicham Mouline (hicham_at_[hidden])
Date: 2010-12-09 10:36:12
Â
Â
-----Original Message-----
From: "Hicham Mouline" [hicham_at_[hidden]]
Date: 09/12/2010 03:22 PM
To: boost-users_at_[hidden]
Subject: Re: [Boost-users] variant over base and derived classes
>>-----Original Message-----
>>From: "Diederick C. Niehorster" [dcnieho_at_[hidden]]
>>Date: 09/12/2010 01:51 PM
>>To: boost-users_at_[hidden]
>>Subject: Re: [Boost-users] variant over base and derived classes
>>(sorry if this is a top post, my phone shows no msg quotes)
>>I'm no expert on this, but isn't there an compile time function to
>>testing if an instance is derived from another (in introspection or
>>something)? You could then maybe sort the variant types for most to
>>least derived and then test untill you find the suitable cast?
>>Just brainstorming pretty much. Hope its useful!
>>Best,
>>Dee
>yes, there is boost::is_base_of or some metafct like that in type_traits.
>not quite sure how to implement the sort though?
>will checkout mpl::sort with binary predicate base_or_derived.
>I have under 10 types, so compile time should be ok
>thanks,
This works. The source is pasted below.
I am however obliged to
1. declare a default-constructed variant
2. call mpl::for_each on the sequence of types in the variant a assign functor to assign to the variant.
Is there a way I can embed/simplify this 2 stage construction?
regards,
Â
Here is the source :-)
#include <iostream>
#include <boost/variant.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <boost/mpl/sort.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/logical.hpp>
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;
}
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