lizarisk
lizarisk

Reputation: 7820

boost::any violates Liskov substitution principle

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

Answers (2)

alfC
alfC

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

SteveLove
SteveLove

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

Related Questions