Boost logo

Boost :

Subject: Re: [boost] [any] boost::get style accessors
From: Stefan (mstefanro_at_[hidden])
Date: 2010-04-28 13:21:40


Christoph Heindl wrote:
> Hi all,
>
> I couldn't find any boost::get<T> style accessors for boost::any, so I
> came up with an implementation that looks something along the
> following lines.
>
> #include <boost/any.hpp>
> #include <boost/call_traits.hpp>
>
> namespace boost {
>
> template<class T>
> typename boost::call_traits<T>::reference get(any &a) {
> return boost::any_cast<typename boost::call_traits<T>::reference>(a);
> }
>
> template<class T>
> typename boost::call_traits<T>::const_reference get(const any &a) {
> return boost::any_cast<typename boost::call_traits<T>::const_reference>(a);
> }
> }
>
> In case it cannot be converted to the desired destination type a
> bad_any_cast exception is thrown.
>
> The above code enables boost.any and boost.variant to be used
> interchangeably as far as boost::get<T> is concerned.
>
> Any thoughts?
>
> Best regards,
> Christoph
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>
You may want to extend this by adding support for get(any*) and get(any
const*). Also, for making them usable interchangeably via boost::get,
you need them to throw the same exception. Therefore, in case you are
using boost::any, you probably want to rethrow bad_any_cast to bad_get.

namespace boost {
   template<class T>
   typename boost::call_traits<T>::reference get(any &a) {
                try {
                        return boost::any_cast<typename boost::call_traits<T>::reference>(a);
                } catch (boost::bad_any_cast const &) { throw(boost::bad_get()); }
   }

   template<class T>
   typename boost::call_traits<T>::const_reference get(const any &a) {
                try {
                        return boost::any_cast<typename
boost::call_traits<T>::const_reference>(a);
                } catch (boost::bad_any_cast const &) { throw(boost::bad_get()); }
   }
        
        template <class T>
        T* get (any *a) {
                return boost::any_cast<T>(a);
        }
        
        template <class T>
        T const* get (const any *a) {
                return boost::any_cast<T>(a);
        }
}

Yours,
   Stefan

P.S. While looking through [1] I noticed that boost::bad_get is missing
a nothrow virtual dtor: virtual ~bad_get() throw() { }
Unless I'm wrong, someone should probably add that there.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk