Reputation: 7820
I've found that it's impossible to extract a reference to a base type from boost::any
which is holding a derived type:
boost::any holder = Derived();
const Base& base_ref = boost::any_cast<const Base&>(holder);
throws a boost::bad_any_cast
exception.
It seems like this is a violation of Liskov substitution principle and not very convenient. Are there any workarounds?
Upvotes: 4
Views: 201
Reputation: 16242
The substitution principle still applies, in the sense that the code compiles and works. The design of boost::any
is such that it raises an exception (and you can recover from it if you want).
An alternative design of boost::any
may choose to do something different. For a more fine grained version of boost::any you can look at Boost.TypeErasure. (Although probably std::unique_ptr
will do the job you want.)
Upvotes: 0
Reputation: 3207
I don't think it "violates" it - boost::any
isn't designed for what you're using it.
It is specifically designed to work with value types (see the docs, to which you already posted a link).
You must any_cast to exactly the type the any variable holds; under the hood, it's checking the typeid. Clearly, const Base&
isn't a match for Derived
in this case.
std::shared_ptr< Base >
provides /almost/ what you seem to want. Or see here for some more info.
Upvotes: 5