Boost logo

Boost :

Subject: Re: [boost] Formal Review Request: Boost.Convert
From: Vladimir Batov (batov_at_[hidden])
Date: 2009-02-26 01:34:41


> From: "Stewart, Robert" <Robert.Stewart_at_[hidden]>
> ...
> I don't think there's any reason to pursue a review until things begin
> to quiesce which doesn't appear likely any time soon, if the current
> discussions are any indication.

Well, that's IMHO too bad. I obviously cannot carry on forever and I do not
see a consensus getting any closer. The crux of the matter (in my view) is
that the convert() functionality is available and IMHO way better than
lexical_cast has to offer. Rejecting it because Spirit can do formatting
better or because convert() does not use Boost.Parameter would be
shortsighted IMHO as in the end people will be still left with nothing -- a
huge hole between lexical_cast and Spirit. Is it realistic/practical
approach? I do not think so. When/If something better comes up, this
functionality will die out by itself.

> I appreciate your excitement, but it
> would be far better to have a well conceived, broadly acceptable
> idea before heading for review. Otherwise, you're quite likely to find
> your library rejected with comments like you're seeing now.

Again, I am not convinced that what I have on offer is badly conceived.
Surely, there's been quite a discussion about names and the 'string'
namespace. However, I hope that well-conceived means quite a bit more than
just names... which we'll never come to an agreement about. So, if it is
really the case that the naming (rather than functionality) will be the
deciding factor for an acceptance or a rejection, maybe it is better to drop
the whole thing altogether.

>> > What about the concern I raised early on about implicit conversions?
> The output value can still be implicitly converted to the callers
> destination
> object. To avoid input and output conversions, you need the likes of
> this:
>
> template <class Out, class In>
> void
> convert(In const &, Out &); // or convert(Out &, In const &)

Aha, now I understand. Passing a parameter by a non-const reference. Yes, as
above we indeed avoid the implicit conversions. That's nice. Never occured
to me. I admit I am allergic :-) to returning results this Pascal-style.
Never grew on me. Sorry. Just not my cup of tea. Will probably do *anything*
just not to have it. :-) Truly sorry.

> Without that, the following might surprise someone:
>
> foo f(convert<double>("1234.5"));

Yes, that's typical of C/C++. Although I admit that after reviewing/looking
at so much of somebody else's code it has never been my major concern. And
isn't a compiler warns us of things like that?

> I had no idea that testing for the default value or
> querying a success flag was what you meant by
> simple and advanced "failure checks."

Wel, calling it "advanced" is probably a bit rich. How about simple and
"better" failure checks. They *are* failure checks, aren't they?

> I think there should be two or three distinct signatures for using the
> conversion facilities:
>
> 1. A call that throws on failure.
> 2. A call that takes a default and always succeeds.
> 3. A call that returns false on failure.

As I indicated, I am not convinced there is such a clear cut as I might be
forced to provide a default (due to no def.ctor) but still want to throw. My
thinking behind convet_to, convert_from is that the latter *is* the
interface. I'd be happy to get rid of #1 (which is convert_to) but I think
it'd better be there for better transition from lexical_cast.

As you indicated in your very first reply to this thread (in relation to
string::is()) #3 will have to actually try the conversion. If I remember
correctly you did not like it much (or did you object to the name only?).

> ...
> With that set of signatures, there's no implied need for a special return
> type that converts implicitly to the destination type and can be queried
> for success, or a throw/nothrow flag. There may yet be a special return
> type to account for specifying the default value as I suggested elsewhere,
> or for some other peculiarity, but it isn't a given.

Again, my real example:

direction dir = convert_from(str, direction::up);

It takes the default because it has to (no def.ctor). It does not mean I do
not want to throw on failure... In real life, I don't. However, then I need
a means to distinguish the failure. With

convert::result<direction> dir = convert_from(str, direction::up);
if (dir.good())

I can achieve that without resorting to your #3 to actually try the
conversion twice.

> I had no idea that you were referring to the formatting facilities
> inherent in the underlying IOStreams implementation. Still,
> there must be a large number of use cases of various kinds
> of UDT and builtin conversions, complete with a variety of
> formatting tasks, to determine if the interface will cope well in
> this context.

I feel there is too much emphasise on formatting. I do not believe convert()
is the tool for it. For good formatting we need good formatting tools
(Spirit?). However, for basic formatting IOStream-based approach works for
me -- I do not need to bring a cannon (Spirit) to shoot a few little birds
(basic formatting).

V.


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