Boost logo

Boost :

Subject: Re: [boost] [convert] Default Syntax Idea
From: Vladimir Batov (batov_at_[hidden])
Date: 2009-02-25 23:42:59


> From: "Hartmut Kaiser" <hartmut.kaiser_at_[hidden]>
>
> Some additional remarks.
>
> 1) Streams have proved to be horrible at formatting. Why stick with this
> scheme?
> ...
> 2) What about more complex conversions like:
> ...
> which brings us directly into the domain of Spirit (and, if you change
> convert for parse, you'll almost get a valid spirit expression, btw). So
> here is my question again. What's the point in duplicating Spirit's
> functionality?
> 3) What about leading/trailing whitespace in the strings to convert?

For me the most important property of lexical_cast (where it all started) is
the ability to plug my own class in to the framework. I need

int i = convert_to<int>(str);
direction dir = convert_to<direction>(str);

and

template<class T>
void foo(T const& instance)
{ ... convert_from(instance); ... }

The mechanism of plugging a user-defined class into the lexical_cast/convert
framework (with op>>, op<<) might be clumsy. However, it is well understood
and readily available.

When I looked at Spirit I did not get an impression that I can do that. Can
I?

As for formatting it is no more limited than IOStream-based formatting. For
many (including me) it is sufficient. And I do not believe convert() should
be looked at as a comprehensive formatter. For me convert() is a better
(much better?) lexical_cast. I have many uses for that. For real formatting
I'll use something completely else.

> 4) Default values should be directly associated with the conversion
> operation in question, any of the syntax' above is misleading. Either have
> default values as a separate parameter to convert(), or use the explicit
> syntax proposed before: convert().default(...).

Yes, I think I've come to a similar conclusion and for the time being I am
favoring the original

convert_from(string, -1/*the default*/)

> 5) Throw/nothrow semantics are _not_ orthogonal to default values, those
> are
> directly depending on each other. I.e. if I specify a default value, I
> don't
> want to get an exception. The opposite is true as well, if I do want to
> get
> an exception, I probably won't specify a default value.

I have to disagree here as for a non-DefaultConstructible class one has to
provide a default. Like

// By default convert_to throws on failure
direction dir = convert_to<direction>(str)

won't compile as it requires direction::direction(). So, I have to write

// By default convert_from does not throw on failure
direction dir = convert_from(str, direction::up) >> boost::dothrow;

In that setting to get the same (as convert_to) throwing behavior as the
default is provided ouf of necessity rather than to shape
throwing/non-throwing behavior.

Equally I cannot see anything out of ordinary if someone might like
convert_to() without the throwing behavior.

// By default convert_to throws on failure
convert<int>::result i = convert_to<int>(str) >> boost::nothrow;
if (i.good())

V.


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