[C++-sig] boost::any

Jens Finkhäuser jens at unwesen.de
Wed Feb 22 20:02:21 CET 2006


Hi!

  The problem is that boost::python converters (please correct me if I'm
wrong, it's been a while) are selected by the compiler at compile time based
on the C++ type you want to convert from/to.
  boost::any is pretty much the same as a python variable, though, and
does not have a type related to the type of object it holds. Rather it can be
thought of as an untyped reference to a typed object.
  The held object has a distinct type such as std::string or int whereas
boost::any stays boost::any regardless of what type of object it holds.
Python variables are similar in that they are basically references to
typed objects.
  That means the C++ compiler can't determine at compile time what type
of object a boost::any holds, and therefore not determine what type of
python object to convert that held object to.

  If as you say you have a limited set of types that your boost::any
holds, you might want to create a simple class hierarchy for them:

    struct foo_base {};
    struct foo_str : public foo_base { std::string m_value; }
    struct foo_int : public foo_base { int m_value; }

  Then you can code and register some trivial converters for foo_str,
foo_int, etc. and hand around vector<shared_ptr<foo_base> > (or
something equivalent) instead of vector<any>.

  To save you some typing, you could make foo_base a template:
    template <typename heldT>
    struct foo_base
    {
        foo_base(heldT const & value)
            : m_value(value)
        {}

        // also define assigment operator and possible conversion
        // operator.

        heldT   m_value;
    };

  Then the definition of foo_str and foo_int becomes shorter and they're
more easily used on the C++ side as well:
    struct foo_str : public foo_base<std::string> {};
    struct foo_int : public foo_base<int> {};

    ...

    foo_int bar(42);
    bar = 12345;
    int a = bar;

Happy hacking!
    Jens



More information about the Cplusplus-sig mailing list