Boost logo

Boost :

Subject: Re: [boost] [lexical_cast] A suggestion
From: David Abrahams (dave_at_[hidden])
Date: 2009-02-08 17:41:50

on Sun Feb 08 2009, Andrey Semashev <> wrote:

> David Abrahams wrote:
>> on Sun Feb 08 2009, Ben Muzal <> wrote:
>>>> In fact, if we put together all the badly needed functionality that
>>>> overlaps with lexical_cast, and give it appropriate interfaces, I'm not
>>>> entirely convinced that there would be much use for lexical_cast
>>>> anymore.
>>> Really what is with all of the "slippery slope" arguments?
>> That's not my concern. My concern is that I don't think lexical_cast is
>> a particularly good interface for its main uses, which could be thought
>> of as "to-string" and "from-string."
> I disagree. lexical_cast was designed to be simple to use, and I think it does it very
> well. The "to-string" and "from-string" conversions, in their simple form, are just
> corner cases.

Eh? What other uses has it got?!

> If I want to simply parse an int, I don't want to make up a Spirit
> grammar for that or even use scanf.

scanf is *way* lighter weight that lexical_cast.

> I need a C++-style of strtol, which is safe in
> terms of buffer allocation and types.

So write that.

> This is what lexical_cast tries to achieve and it does, to some
> degree. I don't know of any other tools that come this close to this
> goal, neither in Boost, nor outside of it.

So write one (just my opinion). lexical_cast means something very
strange and overly-general, and we should write something targeted at
the real-world uses people actually have.

>>> People are not asking for the kitchen sink. We just want a nothrow
>>> version of the cast and to do that, a default value is needed.
>> I wouldn't say that. boost::optional is another option. In fact, if
>> boost::optional doesn't already provide the exact streaming operator you
>> need, I'd be a little surprised. If it has no streaming operator, we
>> could consider adding the needed one. If it has the wrong streaming
>> operator, it would be pretty easy to invent template nothrow, such that you
>> can write
>> optional<Foo> = lexical_cast<nothrow<Foo> >( something )
> I've already expressed myself on this. I just want to add that optional does define
> its streaming operators, and the way they work is no compatible with the goal we're
> trying to achieve with this extension.

Then it's easy enough to define the derived template that *is*
compatible... although as I've said before I don't think lexical_cast is
the right tool for this job anyway.

>>> Lots of times there are cases when a default value simply will not be
>>> acceptable, but quite often one will. Why can't it be easy to support
>>> both models?
>> I just don't think lexical_cast is the interface we need for most
>> convenient string conversions.
> Do you have a better interface in mind?

It would take some thought and discussion to perfect, but just off the
top of my head, I'd want something like this:

namespace str
  template <class T>
  struct value
      operator T() const; // throws iff parse unsuccessful
      bool parsed() const; // true iff parse succecssful

  template <class String, class T>
  string::as<T>(String const&);

  template <class String, class T>
  typename enable_if<is_integral<T>, string::value<T> >::type
  string::as<T>(String const&, unsigned base);

  template <class T>
  to_str(T const& x);

  template <class String, class T>
  to_str(T const& x);

>>> I had not even heard of the <optional> library until reading this
>>> thread. I might update my little boost extension after checking to
>>> see how <optional> affects performance and code bloat -- but really,
>>> <optional> looks rather more complicated than necessary.
>> It has exactly the right semantics, and it tells you more than the
>> version with the default does. With the default, you can't tell whether
>> there was any valid input there or not, because the value represented in
>> the input could be the same as the default.
> The point is, often I don't care if the default was actually read from the string or
> taken from the argument.

Yes, but sometimes you will.

Dave Abrahams
BoostPro Computing

Boost list run by bdawes at, gregod at, cpdaniel at, john at