Boost logo

Boost :

From: Ferdinand Prantl (prantlf_at_[hidden])
Date: 2008-07-09 10:36:57


Hello,

I would like to improve usage of boost::any with text (char*) constants.
This would be the goal:

    boost::any foo("foo");

    boost::any bar;
    bar = "bar";

Currently the compiler (MSVC 2008 in my case) complains about it:

    ...\boost\any.hpp(117) : error C2536: 'boost::any::holder<
        ValueType>::boost::any::holder<ValueType>::held'
        : cannot specify explicit initializer for arrays

There are more ways to make it compiled, all of them either with an extra
cast or object construction:

    boost::any foo(static_cast<const char *>("foo"));
    boost::any foo((const char *) "foo");
    boost::any foo(std::string("foo"));

Supposing there is no way to persuade the compiler to consider the constant
not to be an array but just a pointer I would suggest adding support for
arrays to boost::any.

I am sorry if it has been discussed already. I found just one thread without
a conclusion (http://lists.boost.org/Archives/boost/2003/01/43460.php). I
asked about it in boost.users and got a nice proposal from Niels Dekker
(http://thread.gmane.org/gmane.comp.lib.boost.user/37189/focus=37414).

I replaced the member "held" in holder<> by a wrapper specialized for arrays:

    template<typename ValueType> struct wrapper
    {
        ValueType data;

        explicit wrapper(const ValueType & value) : data(value) {}
    };

    template<typename ElementType, std::size_t NumberOfElements>
    struct wrapper<ElementType[NumberOfElements]>
    {
        typename remove_const<ElementType>::type data[NumberOfElements];

        explicit wrapper(const ElementType (& value)[NumberOfElements])
        {
            std::copy(value, value + NumberOfElements, data);
        }
    };

A new constructor in boost::any makes use of it:

    template<typename ElementType, std::size_t NumberOfElements>
    any(const ElementType (& value)[NumberOfElements])
      : content(new holder<ElementType[NumberOfElements]>(value)) {}

This solution is more complicated but it makes the instance of boost::any
own the copy of array just like its for scalar objects. Alternatively,
instead of wrapping a copy of the array, I could store just a pointer to
it without any other changes in bost::any (I want to use just constants
in my example):

    template<typename ElementType, std::size_t NumberOfElements>
    any(const ElementType (& value)[NumberOfElements])
      : content(new holder<const ElementType*>(value)) {}

I am attaching a patch to any.hpp from boost 1.35.0. I could provide a test
for it too.

What do you think about it? Shall I create a feature request for it?

Thank you,
Ferda




Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk