Boost logo

Boost Users :

From: Terje Slettebų (tslettebo_at_[hidden])
Date: 2005-01-29 21:54:29

>From: "Yuval Ronen" <ronen_yuval_at_[hidden]>

> Terje Slettebų wrote:
> > I've brought this thread to Kevlin Henney's attention, as I've tended to
> > take care of lexical_cast related questions on the list (including
> > forwarding things needing his consideration, such as any changes to
> > lexical_cast, to him). I'm replying here to let you know that your
report is
> > being taken care of.
> Many, many thanks!

Thanks, yourself. :) Feedback is always welcome (regardless who's library it
is); it's an opportunity to improve it.

> >>1. lexical_cast(Source arg) takes the source argument by value. Why not
> >>by const& ? Calling lexical_cast(some_basic_string) now makes a copy of
> >>the source argument for no reason.
> >
> > I heard from Kevlin that the reason was that there originally were some
> > issues with binding to string literals. Changing it to use const
> > in my local copy still gives a lot of error messages, having to do with
> > std::numeric_limits being used in the implementation. If we find a way
> > fix this (yet letting it still work on compilers with no class template
> > partial specialisation, like MSVC 6), without breaking existing
> > then apparently, this change should be ok. If anyone makes a patch for
> > it would be welcome.
> Hmmm, interesting. I'll give it a look. Maybe I'll be lucky enough to
> think of something...

I've been looking at this, as well, and after trying one approach (doing a
compile-time switch to select between the ordinary, and a "dummy"
std::numeric_limits (if the source type is an array)), I bumped into another
problem: the specialisations for wchar_t, which assumes "const wchar_t *",
not "const wchar_t[...]". This might again be fixed, using partial
specialisation, to work with array, but another approach could be to "go
back to square one" and do the array-to-pointer decay "manually":

    template<typename Target, typename Source>
    Target lexical_cast(const Source &arg)
        // Array-to-pointer decay

        typedef typename mpl::if_<
>::type NewSource;

        detail::lexical_stream<Target, NewSource> interpreter;
        Target result;

        if(!(interpreter << arg && interpreter >> result))
        return result;

This passes all tests on Intel C++ 7.1, MSVC 7.1 and g++ 3.2. I've sent it
as a suggestion to Kevlin, as well, I think he's pretty busy with other
things. Anyone having a better suggestion than the above is of course
welcome to contribute it. One thing about the above change is that it
requires a few more includes, but this is really the simplest way I found to
be able to use pass by const reference for lexical_cast.

The additional includes are:

#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/remove_bounds.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/mpl/if.hpp>



Boost-users list run by williamkempf at, kalb at, bjorn.karlsson at, gregod at, wekempf at