Search code examples
c++c++11poco-libraries

How to get integer out of Poco::Any


I use Poco::Any with various integer types, e.g.:

Poco::Any x = 15;
Poco::Any y = (size_t)15;
Poco::Any z = 15L;

Later on I want to work with an integer value:

void func(Poco::Any &a)
{

How can I extract any integer out of this? One way would be:

long n;
if ( auto *p = Poco::AnyCast<int>(&a) )
    n = *p;
else if ( auto *p = Poco::AnyCast<long>(&a) )
    n = *p;

and repeat for every integral type. But this is ugly. Is there a better way?

I have tried:

Poco::Dynamic::Var var(a);
auto n = var.convert<int>(var);

however this throws an exception which comes from VarHolder.h:

virtual void convert(Int32& val) const;
    /// Throws BadCastException. Must be overriden in a type
    /// specialization in order to suport the conversion.

Solution

  • Poco::Any (which is a port of boost:any) is essentially a "one-way road" in regards to types - you can put literally anything into it but, when you want to get the value out, you have to know exactly what is inside; in that sense, any is stricter than the C++ language itself.

    DynamicAny (a.k.a. Poco::Dynamic::Var) is built on the any foundation, "softening" it on the data retrieval side; it was introduced precisely to alleviate that constraint.

    See DynamicAny, Part I for an in-depth explanation:

    Although it provides a mechanism for dynamic type discovery (Listing 2.), boost::any does not itself get involved into such activity, nor is it willing to cooperate in implicit conversions between values of different types.

    So, if you want to stick with Poco::Any, you will have to discover what is in it:

    void func(Poco::Any &a)
    {
      long n;
      if (a.type() == typeid(int))
        n = Poco::AnyCast<int>(a);
      else if (a.type() == typeid(long))
        n = Poco::AnyCast<long>(a);
      // ...
    }