7

I am using an external library that has a method which accepts a void*

I want this void* to point to an object contained within a boost::any object.

Is it possible to get at the address of the content of a boost::any object?

I'm trying to play with myAny.content but no luck so far! I'm hoping some combination of dynamic_cast or unsafe_any_cast will give me what I need.

Thanks!

user1488777
  • 125
  • 4

2 Answers2

5

You can use boost::any_cast to get a pointer to the underlying type (provided you know it at compile time).

boost::any any_i(5);

int* pi = boost::any_cast<int>(&any_i);
*pi = 6;

void* vpi = pi;
Chad
  • 18,706
  • 4
  • 46
  • 63
  • What is this code actually doing? It looks like it is casting the address itself into an int. How come that works? – ftvs Sep 27 '13 at 04:33
  • 1
    That's what `boost::any_cast` does. It has similar semantics as `dynamic_cast`. In this case, casting to an `int*` will succeed, because the underlying type stored is an int. Casing to some other pointer type (say `float*`), would result in a `nullptr` being returned. Casting to a reference type will either succeed, or throw a `boost::bad_any_cast` exception. `boost::any` works only on exact type matches, it uses `typeid` for matching if I recall correctly. – Chad Sep 27 '13 at 14:55
3

This isn't possible, unfortunately; boost::any_cast will refuse the cast if the type is distinct from the contained type.

If you're willing to use an unsupported internal hack, the current version of the header has an undocumented and unsupported function boost::unsafe_any_cast which (as its name suggests) bypasses the type check performed by boost::any_cast:

boost::any any_value(value);
void *content = boost::unsafe_any_cast<void *>(&any_value);

The header has this to say about unsafe_any_cast:

// Note: The "unsafe" versions of any_cast are not part of the
// public interface and may be removed at any time. They are
// required where we know what type is stored in the any and can't
// use typeid() comparison, e.g., when our types may travel across
// different shared libraries.
ecatmur
  • 152,476
  • 27
  • 293
  • 366
  • This should be part of the documented interface, so `boost::any` could be used with legacy code that uses `void*`. Saddest of all, `std::experimental::any` doesn't seem to even have an `unsafe_any_cast`. – alfC Jul 14 '16 at 09:49