Boost logo

Boost Users :

From: Ferdinand Prantl (prantlf_at_[hidden])
Date: 2008-06-30 11:57:03


Hello,

I would like to ask you about the best solution to initialize a
boost::any instance with a C-string constant. Both the most legible
(IMHO) possibilities fail:

    boost::any foo("foo");

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

Compiler (MSVC 2008 in my case) complains about them:

    ...\boost\any.hpp(117) : error C2536:
'boost::any::holder<ValueType>::boost::any::holder<ValueType>::held'
            : cannot specify explicit initializer for arrays
      with [ ValueType=const char [4] ]
    ...\boost\any.hpp(134) : see declaration of
'boost::any::holder<ValueType>::held'
      with [ ValueType=const char [4] ]
    ...\boost\any.hpp(115) : while compiling class template
              member function
'boost::any::holder<ValueType>::holder(ValueType (&))'
      with [ ValueType=const char [4] ]
    ...\boost\any.hpp(41) : see reference to class template instantiation
              'boost::any::holder<ValueType>' being compiled
      with [ ValueType=const char [4] ]
    ...\test.cpp(10) : see reference to function template instantiation
              'boost::any::any<const char[4]>(ValueType (&))' being compiled
      with [ ValueType=const char [4] ]

Obviously the string constant is considered of the type chat[4]
which lacks CopyConstructible and Assignable requirements. Wrapping
the constant in some expression which satisfies the requiremenst
spoils the beauty of a simple code or brings unnecessary (for the
constant handling) object:

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

Such solutions were suggested in the thread
http://lists.boost.org/Archives/boost/2003/01/43460.php but I was
hoping there could be something better. I suppose there is no way
to persuade the compiler to consider the constant to be const char *...

Why has not been the following constructor added to boost::any?
The array would make it there passing just one conversion:

    template<typename ValueType> any(const ValueType * value)
        : content(new holder<const ValueType *>(value))
    {}

Someone could say that that it is more error prone because it enables
storing a pointer which can be invalid as soon as the boost::any
instance leaves the scope but the error can be made anyway:

    boost::any foo(std::string("foo").c_str());

Another possibility would be to match the array type exactly but it
has probably no benefit:

    template<typename ValueType> any(const ValueType value [])
        : content(new holder<const ValueType *>(value))
    {}

Do you see any problems with such constructors? How do you use
string constants with boost::any?

Thank you,
Ferda Prantl


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