Subject: Re: [boost] [variant] Common base type of variant sub-types
From: Mathias Gaunard (mathias.gaunard_at_[hidden])
Date: 2010-01-09 07:25:40


Adam Badura wrote:

> Obviously it would not be wise to provide a function wrapper for each
> and every visitor. However the extended "get" I proposed is unique in
> its ways.

But it wouldn't be 'get'.
There is a reason why it works like this. It's designed to test and
extract for a specific type in one of the variant possibilities, without
doing any implicit conversion.

Adding the enhancement you suggest would change the meaning of 'get' and
potentially break other code.
So I think it would be best as a separate function.

Here is a possible implementation:

namespace boost
{

namespace detail
{

template<typename T>
struct extract_visitor : static_visitor<T&>
{
     T& operator()(T& t) const
     {
         return t;
     }

     T operator()(...) const
     {
         throw bad_visit();
     }
};

template<typename T>
struct extract_pointer_visitor : static_visitor<T*>
{
     T* operator()(T& t) const
     {
         return &t;
     }

     T* operator()(...) const
     {
         return 0;
     }
};

} // namespace detail

template<typename T, typename Variant>
T& extract(Variant& v)
{
     return apply_visitor(detail::extract_visitor<T>(), v);
}

template<typename T, typename Variant>
const T& extract(const Variant& v)
{
     return apply_visitor(detail::extract_visitor<const T>(), v);
}

template<typename T, typename Variant>
T* extract(Variant* v)
{
     return apply_visitor(detail::extract_pointer_visitor<T>(), *v);
}

template<typename T, typename Variant>
const T* extract(const Variant* v)
{
     return apply_visitor(detail::extract_pointer_visitor<const T>(), *v);
}

} // namespace boost

> Secondly
> it provides for variant a feature available in union.

That could only work with unions if the types are binary compatible,
which isn't necessarily the case.