Boost logo

Boost Users :

From: Angus Leeming (angus.leeming_at_[hidden])
Date: 2004-05-06 03:34:58


Mailing List wrote:

> Greetings all, as I'm new to this list, I'll keep my query short.
>
> It was suggested to me to use boost::any to store numeric values of
> whatever type (int, float, double, etc) so that I could use one
> std::list to store multiple values.
>
> I've looked through the header (any.hpp) and I admit it's a little
> hard for me to follow. I'm not what you'd call a superprogrammer...
> yet. :)
>
> I understand how to store a value in the boost::any object, but I'm
> not clear on how one would get that value back later (for display on
> screen, etc).

> Example:
>
> boost::any value1;
> boost::any value2;
> boost::any value3;
>
> value1 = 127.915;
> value2 = 17;
> value3 = value1.getwhatevervalue() + value2.getwhatevervalue();

Boost.Any isn't a panacea. It won't automatically compute the type for
you and 'just do the right thing'. You're essentially looking for
'resultof' which doesn't exist in c++ yet.

With Boost.Any you have to explicitly specify the return type. The
tools to use are boost::any::type and boost::any_cast.

        boost::any const value1(float(127.915));
        if (value1.type() == typeid(float)) ...

        float result = boost::any_cast<float>(value1);

The latter will throw a bad_any_cast exception if you attempt to cast
to anything other than the stored type.

I've coded up your example code below. Not pretty, but does seem to do
the right thing.

HTH,
Angus

#include <boost/any.hpp>
#include <iostream>

class number_store {
        enum Type {
                Int,
                Double
        };

        Type type;
        boost::any data;
public:

        number_store(int d) : type(Int), data(d) {}
        number_store(double d) : type(Double), data(d) {}

        bool is_int() const { return type == Int; }
        bool is_double() const { return type == Double; }

        int as_int() const { return boost::any_cast<int>(data); }
        double as_double() const { return boost::any_cast<double>(data); }

        void operator+=(number_store const & other)
        {
                if (type == Int) {
                        if (other.type == Int) {
                                data = as_int() + other.as_int();
                        } else {
                                data = as_int() + other.as_double();
                        }
                } else {
                        if (other.type == Int) {
                                data = as_double() + other.as_int();
                        } else {
                                data = as_double() + other.as_double();
                        }
                }
        }
};

int main()
{
        number_store const value1(double(127));
        number_store const value2(int(17));

        std::cout << "value1 has type "
                  << (value1.is_int() ? "int" : "double")
                  << '\n'
                  << "value2 has type "
                  << (value2.is_int() ? "int" : "double")
                  << std::endl;

        number_store value3 = value1;
        value3 += value2;

        std::cout << "value3 has type "
                  << (value3.is_int() ? "int" : "double")
                  << " and value "
                  << (value3.is_int() ? value3.as_int() : value3.as_double())
                  << std::endl;

        return 0;
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net