2

It looks like calls to boost::any_cast<T>(any&) call some expensive typechecking to make sure that the cast is valid. Specifically, it calls performs the following test to make sure the cast is legal:

std::strcmp(operand->type().name(), typeid(ValueType).name()) == 0

If the cast is legal, the code then performs a static_cast.

This seems useful for debug mode, but is rather slow for production code. Is there any way to skip the strcmp?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
BenRI
  • 724
  • 6
  • 17
  • If you disable the type checking in `boost::any`, how does it really differ from just using a `void *` and casting it yourself? – FatalError May 16 '12 at 23:02
  • @FatalError : A `boost::any` owns its object, a `void*` does not (and cannot). That said, I agree with the sentiment that if one cares about performance, they probably shouldn't be using `boost::any` to begin with. – ildjarn May 16 '12 at 23:06
  • 5
    @ildjarn: True, but I think he meant in terms of type safety. The entire point of `boost::any` is to keep anyone from casting it to the wrong type, yet the questioner seems to be asking exactly how to not do that. Just don't use `boost::any`! – GManNickG May 16 '12 at 23:07
  • 1
    Wouldn't boost::any retain some usefulness if the typechecking was only disabled #ifdef NDEBUG or #ifdef BOOST_ANY_NO_TYPE_CHECK? – BenRI May 17 '12 at 00:02
  • 1
    @BenRI : Maybe, but I don't think promoting easy UB is one of Boost.Any's design goals. ;-] – ildjarn May 17 '12 at 00:24
  • 1
    @BenRI: What do you mean *retain* some usefulness? It's quite useful as it is. It's pretty arrogant to say, "this isn't working for me, so it's useless for everyone". Maybe it's your program that's designed wrong. And like other's have said, the entire point is type safety. Don't need it? Don't use `boost::any`. – GManNickG May 17 '12 at 00:47

1 Answers1

5

boost::any includes a set of undocumented ValueType * unsafe_any_cast(any * operand) functions that do what you want for any* operands.

You could take the address of your reference to get what you want, or since Boost is open source, you could patch in a set of these function templates to take an any& operand.

Then just make a wrapper that uses the safe versions in debug builds and the unsafe versions in release builds. However, I'd make at least one further addition - the debug wrappers should catch the exception thrown for an invalid cast and invoke the debugger or crash the program so that when running in debug mode those invalid casts aren't handled in a way that hides the fact that the release build would have undefined behavior.

Also keep in mind that Boost reserves the right to remove the unsafe versions:

// Note: The "unsafe" versions of any_cast are not part of the
// public interface and may be removed at any time.

So if you decide to use these functions (or patch any.hpp to extend them), you're buying into some level of maintenance obligation that may or may not be acceptable depending on who your code might be deliverable to.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760