Ben Hymers
Ben Hymers

Reputation: 26546

boost::any_cast - throw only when an implicit conversion isn't available?

I want boost::any_cast<T> to only throw an exception when the type of the any doesn't have an implicit conversion to T. The normal behaviour seems to be to throw an exception if the type of the any is not T, regardless of implicit conversions.

Example:

boost::any a = 1;
boost::any_cast<int>(a); // This succeeds, and rightfully so
boost::any_cast<long>(a); // I don't want this to throw
boost::any_cast<Widget>(a); // I want this to throw

Could anyone tell me if there's a simple way to get the functionality I want, or better yet give me a good reason for why the existing behaviour is the way it is?

Upvotes: 4

Views: 3501

Answers (2)

Emil
Emil

Reputation: 381

any_cast can't do it but if the base and derived types are complete (which they usually are for types that are in a hierarchy) you could implement your own system which converts by means of throw and catch, since throwing a pointer to a derived type can be caught as a base pointer type.

Upvotes: -1

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 507025

Well you can't do it. The any mechanism works like this:

struct base {
    virtual ~base() { }
};

template<typename T>
struct concrete_base : base {
    T t;
    concrete_base(T t):t(t) { }
};

struct my_any {
    base * b;

    template<typename T>
    my_any(T t):b(new concrete_base<T>(t)) { }

    template<typename T>
    T any_cast() { 
        concrete_base<T> * t = dynamic_cast< concrete_base<T>* >(b);
        if(!t) throw bad_any_cast();
        return t->t;
    }
};

I hope it's clear what the above does. There is no way you could do what you are looking for i think. The reason is that there is no information about the type kept that could prove useful here. RTTI doesn't provide it.

Upvotes: 5

Related Questions