[convert] Now with Boost.Parameter interface.

View: New views
20 Messages — Rating Filter:   Alert me  
< Prev | 1 - 2 - 3 | Next >

Re: [convert] Now with Boost.Parameter interface.

by Gottlob Frege :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

And in addition to the unexpected effects, it just doesn't read or look right.

   from(str, 0)(more stuff);

really makes me think 'more stuff' happens AFTER the conversion. This
is one of the examples of why C programmers and many other
language-ites just shake their heads at us. We can't seem to stick to
writing code that even follows the rules of the language. (obviously
the code, using a proxy, does follow the rules, but it doesn't look
like it does).

If you really want the multiple function call syntax, could we at
least somehow put it first?
ie (just one possible way), and note that 'convert' has become 'converter':

   converter<int>(locale_ = loc)(throw_ = true).from(str, 0);

And as a bonus, I can reuse the 'converter' on the next line if I
store it somewhere.

And you can still use the simple 'convert' (without the er) if no
extra params are needed:

   convert<int>::from(str, 0)

And now it really does return an int.

Tony

On Wednesday, July 1, 2009, David Abrahams <dave@...> wrote:

>
> on Wed Jul 01 2009, "Vladimir Batov" <batov-AT-people.net.au <http://batov-AT-people.net.au>> wrote:
>
>> From: "David Abrahams" <dave@...>
>>> ...  What's wrong with
>>>
>>>  int i = convert<int>::from(str, 0, locale_ = new_locale, throw_ = true);
>>
>> I personally to not feel there is anything wrong per se with the above. The reason I
>> did not pursue it was that it introduces a limit on the number of the parameters and I
>> did not see it offering any major advantages to balance that shortcoming over the
>> supported
>>
>> int i = convert<int>::from(str, 0)(locale_ = new_locale)(throw_ = true);
>>
>> On the other hand the supported interface seems to scale considerably better and is no
>> longer to type:
>>
>> int i = convert<int>::from(str, 0)(locale_ = new_locale)(throw_ = true);
>> int i = convert<int>::from(str, 0, locale_ = new_locale, throw_ = true);
>
> But again, it has the downside that none of your calls above can return
> an actual int.  That can have unexpected effects, e.g. in
>
>    some_function_template( convert<int>::from(str, 0) )
>
> when the deduced template argument is actually your proxy type.
>
> --
> Dave Abrahams
> BoostPro Computing
> http://www.boostpro.com
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [convert] Now with Boost.Parameter interface.

by Vladimir Batov :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> From: "David Abrahams" <dave@...>
> ...
>> int i = convert<int>::from(str, 0)(locale_ = new_locale)(throw_ = true);
>> int i = convert<int>::from(str, 0, locale_ = new_locale, throw_ = true);
>
> But again, it has the downside that none of your calls above can return
> an actual int.  That can have unexpected effects, e.g. in
>
>   some_function_template( convert<int>::from(str, 0) )
>
> when the deduced template argument is actually your proxy type.

Yes, that is a fair point. The way around it is

    some_function_template( convert<int>::from(str, 0).value() )

Returning the value (rather than a proxy) was *very* tempting... but seemed
*very* limiting. Like chaining of additional configuration parameters
(notably i/o stream manipulatiors) would be impossible. Still, I'll take
another look if I can see things differently this time around.

V.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [convert] Now with Boost.Parameter interface.

by Vladimir Batov :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> From: "Gottlob Frege" <gottlobfrege@...>
> And in addition to the unexpected effects,
> it just doesn't read or look right.

   from(str, 0)(more stuff);

> really makes me think 'more stuff' happens AFTER the conversion.

Well, I am not sure I can agree that those mentioned "unexpected effects" is
such a big deal. The "problem" with the deduced template parameters is the
only "problem" I've come across so far. In fact, that issue is not unique to
'convert' and 'convert' addresses that is a fairly standard way. Granted,
not having that 'hack' would be better.

> This is one of the examples of why C programmers and many other
> language-ites just shake their heads at us. We can't seem to stick to
> writing code that even follows the rules of the language. (obviously
> the code, using a proxy, does follow the rules, but it doesn't look
> like it does).

I hear you. :-)

> If you really want the multiple function call syntax, could we at
> least somehow put it first?
> ie (just one possible way), and note that 'convert' has become
> 'converter':
>
>    converter<int>(locale_ = loc)(throw_ = true).from(str, 0);

I am not sure why 'convert' had to become 'converter' so for the moment I'll
stick with what exists already. That makes it

int i = convert<int>(locale_=loc)(throw_=true).from(str,0);
vs
int i = convert<int>::from(str,0)(locale_=loc)(throw_=true);

I am not sure. I'll have to sleep on it. Something is drawing me to the
syntax you suggest but I am not sure what it is. What I like about the
existing syntax though is its incremental flowing style:

int i = convert<int>::from(str,0); // simple form
int i = convert<int>::from(str,0)(locale_=loc); // with locale
int i = convert<int>::from(str,0)(locale_=loc)(throw_=true);

The above looks more predictable and flows better for me.

> And as a bonus, I can reuse the 'converter' on the next line if I
> store it somewhere.

Yes, that functionality is already available (like one can use the same
conversion with an algorithm) although maybe not in such an explicit form.
That functionality was suggested, fairly straightforward to achieve within
the existing framework, just did not get time to make it happen.

> And you can still use the simple 'convert' (without the er) if no
> extra params are needed:
>
>   convert<int>::from(str, 0)

What I feel uncomfortable with is that "if this, use converter, if that, use
convert, if this, use one syntax, if that some other syntax". To me that
lacks predictability which is the first step towards familiarity that leads
to confidence and acceptance (something any library writer wants).

> And now it really does return an int.

After looking at the problem for a while I am not sure that 'convert' really
returning a straight 'int' is achievable without denying many legitimate
use-cases. Though I by no means can claim the last word in the domain.

V.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [convert] Now with Boost.Parameter interface.

by Stewart, Robert :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Gottlob Frege wrote:

[please don't top post]

> And in addition to the unexpected effects, it just doesn't
> read or look right.
>
>    from(str, 0)(more stuff);
>
> really makes me think 'more stuff' happens AFTER the
> conversion. This is one of the examples of why C programmers
> and many other language-ites just shake their heads at us. We
> can't seem to stick to writing code that even follows the rules
> of the language. (obviously the code, using a proxy, does
> follow the rules, but it doesn't look like it does).

That's probably why I've thought the named function approach clearer:

   from(str, 0).more().stuff();

It deviates less from the usual, though I do acknowledge your complaint about the sequence.  Here's another way to make it more explicit:

   from(str, 0).with(more stuff);

> If you really want the multiple function call syntax, could we
> at least somehow put it first? ie (just one possible way), and
> note that 'convert' has become 'converter':
>
>    converter<int>(locale_ = loc)(throw_ = true).from(str, 0);

Why not with the syntax Dave has been suggesting:

   converter<int>(locale_ = loc, throw_ = true).from(str, 0);

_____
Rob Stewart                           robert.stewart@...
Software Engineer, Core Software      using std::disclaimer;
Susquehanna International Group, LLP  http://www.sig.com

IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [convert] Now with Boost.Parameter interface.

by Gottlob Frege :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Sorry it is a limitation of the iPhone.
It is very hard to edit emails.

:(

Tony

(I'll try not to email from the phone too much)


On Thursday, July 2, 2009, Stewart, Robert <Robert.Stewart@...> wrote:

> Gottlob Frege wrote:
>
> [please don't top post]
>
>> And in addition to the unexpected effects, it just doesn't
>> read or look right.
>>
>>    from(str, 0)(more stuff);
>>
>> really makes me think 'more stuff' happens AFTER the
>> conversion. This is one of the examples of why C programmers
>> and many other language-ites just shake their heads at us. We
>> can't seem to stick to writing code that even follows the rules
>> of the language. (obviously the code, using a proxy, does
>> follow the rules, but it doesn't look like it does).
>
> That's probably why I've thought the named function approach clearer:
>
>    from(str, 0).more().stuff();
>
> It deviates less from the usual, though I do acknowledge your complaint about the sequence.  Here's another way to make it more explicit:
>
>    from(str, 0).with(more stuff);
>
>> If you really want the multiple function call syntax, could we
>> at least somehow put it first? ie (just one possible way), and
>> note that 'convert' has become 'converter':
>>
>>    converter<int>(locale_ = loc)(throw_ = true).from(str, 0);
>
> Why not with the syntax Dave has been suggesting:
>
>    converter<int>(locale_ = loc, throw_ = true).from(str, 0);
>
> _____
> Rob Stewart                           robert.stewart@...
> Software Engineer, Core Software      using std::disclaimer;
> Susquehanna International Group, LLP  http://www.sig.com
>
> IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [convert] Now with Boost.Parameter interface.

by Scott McMurray-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

2009/7/2 Stewart, Robert <Robert.Stewart@...>:
>
> Why not with the syntax Dave has been suggesting:
>
>   converter<int>(locale_ = loc, throw_ = true).from(str, 0);
>

To me, that's the nicest one yet proposed.

And it'd be quite reasonable, instead of statics, to just use
convert<int>().from(str, 0), since that's already common from function
objects.

And actually, why not spell from() as operator(), so it can be a
proper function object?

transform( istream_iterator<string>(cin), istream_iterator<string>(),
back_inserter(v), convert<int>(locale_ = loc, base_ = 16, throw_ =
false, default_ = 0));
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [convert] Now with Boost.Parameter interface.

by Gottlob Frege :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thursday, July 2, 2009, Scott McMurray <me22.ca+boost@...> wrote:
> 2009/7/2 Stewart, Robert <Robert.Stewart@...>:
>>
>> Why not with the syntax Dave has been suggesting:
>>
>>   converter<int>(locale_ = loc, throw_ = true).from(str, 0);
>>
>
> To me, that's the nicest one yet proposed.
>

I think that the only complaint was that it limits the number of
params, whereas the other version does not. But if you have more than
10 params, I think you have bigger problems.


> And it'd be quite reasonable, instead of statics, to just use

I didn't see that as a static, but as a constructor call.

> convert<int>().from(str, 0), since that's already common from function
> objects.
>
> And actually, why not spell from() as operator(), so it can be a
> proper function object?
>
> transform( istream_iterator<string>(cin), istream_iterator<string>(),
> back_inserter(v), convert<int>(locale_ = loc, base_ = 16, throw_ =
> false, default_ = 0));
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [convert] Now with Boost.Parameter interface.

by Scott McMurray-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

2009/7/2 Gottlob Frege <gottlobfrege@...>:
>
>> And it'd be quite reasonable, instead of statics, to just use
>
> I didn't see that as a static, but as a constructor call.
>

Sorry, I was referring to using convert<int>::from when you don't need
to pass parameters to the constructor.
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [convert] Now with Boost.Parameter interface.

by Vladimir Batov-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> Scott McMurray <me22.ca+boost <at> gmail.com> writes:
>
>>   converter<int>(locale_ = loc, throw_ = true).from(str, 0);
>
> To me, that's the nicest one yet proposed.
>
> And it'd be quite reasonable, instead of statics, to just use
> convert<int>().from(str, 0), since that's already common from function
> objects.

I am not sure I can immediately see the visual advantage of

    convert<int>().from(str, 0)
over
    convert<int>::from(str, 0)

Functionally, (with everything else equal) #1 has an additional overhead of
creating an object.

> And actually, why not spell from() as operator(), so it can be a
> proper function object?

If I remember correctly, one of the reasons for 'from' was the explicit
directiveness of the conversion -- convert<int>::from(string).

Functionally, the advantage of a static 'from' function over op() is that the
former allows to delay implementation specialization (and, therefore, converter
instantiation) until we know both -- TypeIn and TypeOut -- conversion types.
It's turned out to be quite important as the actual conversion implementation
equally depends on TypeIn as on TypeOut. For that reason I feel that
constructing an instance of converter<TypeOut> (with only TypeOut known) is very
limiting.

V.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [convert] Now with Boost.Parameter interface.

by Vladimir Batov :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> From: "Stewart, Robert" <Robert.Stewart@...>
> Gottlob Frege wrote:
>
>> And in addition to the unexpected effects, it just doesn't
>> read or look right.
>>
>>    from(str, 0)(more stuff);
> ...
> Here's another way to make it more explicit:
>
>   from(str, 0).with(more stuff);

Yes, I think I like Rob's 'with'. I feel this does rectify whatever "it just
doesn't read or look right" there might be and it can be added quite easily
to he existing interface. I personally like with() better than suggested
before locale(), throw_(), etc. as it's only one new method to remember.

My only concern is that spelling out everything has limited value -- only
for an uninitiated person. For a seasoned user having to explicitly spell
out everything is likely to be irritating. I am certainly talking about my
own experiences. Is "str.append(other-string)" really better/clearer then
"str += other-string"? I expect anyone who grew up with C to appreciate the
latter syntax. To me it is pretty much the same with "from(str, 0)(more)" as
it deploys a known C++ technique of chaining with op(). That's why (given
choice) while learning/playing I might probably start with

    from(str, 0).with(more stuff);

but once familiar with it, I'll likely switch to

    from(str, 0)(more stuff);

Maybe provide both?

>> If you really want the multiple function call syntax, could we
>> at least somehow put it first? ie (just one possible way), and
>> note that 'convert' has become 'converter':
>>
>>    converter<int>(locale_ = loc)(throw_ = true).from(str, 0);
>
> Why not with the syntax Dave has been suggesting:
>
>   converter<int>(locale_ = loc, throw_ = true).from(str, 0);

converter<int>(locale_ = loc)(throw_ = true)
converter<int>(locale_ = loc, throw_ = true)

To me the two above are only marginally different (and hardly visually
different). Is it possible to identify what advantages of #2 there might be?
As for #1, it is an instantly-recognizable and fairly common technique of
chaining with op(). Unlike #2 it scales up with no issues. Providing a
limited number of parameters is "cheating" as Alexantrescu puts it in his
"Modern Design" book. :-) I understand that in practical terms it might not
make any difference here... but why introduce a limitation when we do not
have to?

As for converter<TypeOut>, I suspect it won't be able to take us far enough
as it does not take into account TypeIn which is important for
implementation specialization. People following this thread might remember
that at one stage the implementation/interface was "convert[er]<TypeIn,
TypeOut>". Then, I feel it was an improvement when we kept internally
"convert[er]<TypeIn, TypeOut>" but externally were able to deduce TypeIn via
a function with convert<TypeOut>::from(TypeIn).

That said, we certainly can re-visit that "convert[er]<TypeIn, TypeOut>".
Then, we'll be able to do the suggested

converter<TypeIn, TypeOut>(local_=loc).from(type-in-value)
converter<TypeIn, TypeOut>(local_=loc)(type-in-value)
converter<TypeIn, TypeOut>(type-in-value)

To me it does have its own beauty and uniformity.

V.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [convert] Now with Boost.Parameter interface.

by Vicente Botet Escriba :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,
----- Original Message -----
From: "Gottlob Frege" <gottlobfrege@...>
To: <boost@...>
Sent: Thursday, July 02, 2009 6:55 PM
Subject: Re: [boost] [convert] Now with Boost.Parameter interface.



On Thursday, July 2, 2009, Scott McMurray <me22.ca+boost@...> wrote:
> 2009/7/2 Stewart, Robert <Robert.Stewart@...>:
>>
>> Why not with the syntax Dave has been suggesting:
>>
>> converter<int>(locale_ = loc, throw_ = true).from(str, 0);
>>
>
> To me, that's the nicest one yet proposed.
>

I think that the only complaint was that it limits the number of
params, whereas the other version does not. But if you have more than
10 params, I think you have bigger problems.


> And it'd be quite reasonable, instead of statics, to just use

I didn't see that as a static, but as a constructor call.

> convert<int>().from(str, 0), since that's already common from function
> objects.
>
> And actually, why not spell from() as operator(), so it can be a
> proper function object?
>
> transform( istream_iterator<string>(cin), istream_iterator<string>(),
> back_inserter(v), convert<int>(locale_ = loc, base_ = 16, throw_ =
> false, default_ = 0));

I have followed this thread and I would like to share with you my view. IMO we need a converter function and a convert free function that returns the To type. With the interface below we should be able to

* make a conversion using a default converter (which could throw if the conversion fails)

int i = convert<int>(str);

* make a conversion using a specific converter constructed form these coverter parameters

int i=convert<int>(str, (locale_ = loc, base_ = 16, throw_ = false, default_ = 0));

Note that we can also have

int i=convert<int>(str, (locale_ = loc)(base_ = 16)(throw_ = false)(default_ = 0));

if the converter_parameters defines the operator().

* transform using a converter functor

transform( istream_iterator<string>(cin), istream_iterator<string>(),
back_inserter(v), converter<int>((locale_ = loc, base_ = 16, throw_ =
false, default_ = 0)));


The class converter_parameters is used to store all the parameters related to the conversion. It should be close to the internal representation of the current converter convert_detail::implementation<TypeIn, TypeOut> but without the TypeIn

template <typename To>
class converter_parameters {
...
}

The converter class is the functor class realizing the conversion using the conversion parameters
template <typename To>
class converter {
    converter();
    converter(converter_parameters<To> const&);
    template <typenam From> To operator()(From);
};

the convert function now return the out type  (To) and not a converter

template <typename To, typename From>
To convert(From f, converter<To> const&cv) {
    return cv(f);
}

template <typename To, typename From>
To convert(From f, converter_parameters<To> const&cvp) {
    converter<To> cv(cvp);
    return convert(f, cv);
}

template <typename To, typename From>
To convert(From f) {
    converter<To> cv;
    return convert(f, cv)
}

I dont' think the current implementation needs to much changes to be adapted to this proposal.

HTH,
Vicente

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [convert] Now with Boost.Parameter interface.

by Vladimir Batov :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> From: "David Abrahams" <dave@...>
>>> I understand how to achieve
>>>
>>> int i=convert<int>::from(str, 0)((locale_=new_locale, throw_=true));
>>>
> You should be able to do it without the double parens.  Is there
> documentation missing?

Dave,

Apologies for not answering your question earlier. I am not sure how I
managed to miss it. The answer is 'no', I do not think there is
Boost.Parameter documentation missing. Unfortunately, my understanding
was/is that to achieve that I have to resort to Boost.Parameter macros which
I managed to avoid so far. I think I understand the non-macros part of
Boost.Parameter. I quite like it and I am comfortable using it.
Boost.Parameter macros seemed too complex and looked too "alien" which
exacerbated my general dislike of macros. Please do not take it as a
criticism of any kind. It's merely my "casual-user" impression which can
easily be wrong as I was not prepared to spend enough time playing with
Boost.Parameter macros.

V.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

[convert] are you mixing default_value and error_value?

by Vicente Botet Escriba :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

I have read the documentation and I think that you are mixing default value with error value. The fact that a type is not DefaultConstructible do not implies that the user wants to have an exception when the conversion fails. This are two orthogonal dimensions.

I think that for these non Default constructible types you can use a trait that gives you a default value for types not having a default constructor. E.g.

template <typename T>
struct default_value_trait {
    static const T value=T();
};

template <>
struct default_value_trait<direction> {
    static const direction value=direction::up;
};

So now you don't need any more to pass the default value as parameter, and the following should compile

direction dir = convert<direction>::from (str);  

and could  throw if conversion fails after minor modification on the implementation.

I suppose you can reach the same effect with the error_value needed when the user want no_thow semantics.

template <typename T>
struct error_value_trait {
    static const T value=T();
};

template <>
struct error_value_trait<direction> {
    static const direction value=direction::down;
};

So the following

direction dir = convert<direction>::from (str)(_thows=false);  

will return direction::down when conversion fails after some modification on the implementation

One more question raise now. Should the fact the conversion throws or not when failing be part of the function type or a function parameter?

Do we need

direction dir = convert<direction, no_thows<> >::from (str);  

or

direction dir = convert<direction>::from (str)(_thows=false);  

Resumein, I think these modifications are important, so the convert function can have always only the From parameter, and the throw semantics is preserved for non DefaultConstructible types.

HTH,
Vicente


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [convert] Now with Boost.Parameter interface.

by Gottlob Frege :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Is it possible to sum up the issues?  Unfortunately some of us have
floated in and out of the conversation, and I, for one, feel that I am
probably missing some important reprecussions of any suggestions I
might make.

ie:

0. using named parameters - is this still debatable, or pretty much decided

1. how to list params:  (locale_ = locale)(throw_ = true) vs (locale_
= locale, throw_ = true) vs ((locale_ = locale, throw_ = true))

2. where to list params:  from(str, 0)(more stuff) vs from(str,
0).with(more stuff) vs (more stuff).from(str, 0)

3. returning an int (well, whatever the To type is)

4. use cases: function object, direct call, etc

5. ?

Tony
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [convert] Now with Boost.Parameter interface.

by Vladimir Batov-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> Gottlob Frege <gottlobfrege <at> gmail.com> writes:
>
> ...
>
> 0. using named parameters - is this still debatable, or pretty much decided

I'd say anything is debatable and open for a discussion. Although some aspects
have been discussed at length when the thread was somewhat more active.

As for "decided" it feels too hard a word as people have varying opinions and
preferences and I am inclined to try to accommodate those preferences (if
possible) rather than "decide" on something. I am trying not to decide on
anything but rather let pieces fall off based on the usage experience. I admit
mainly using my own experience as a guide as I do not have much other input.

As for named parameters, the interface is there and I was not rushing to take it
out as I remember some people argued strongly in its favor. My only
complain/observation was that my personal impression was that it was only of
limited usage (for locale and throw). I was not alone advocating that stretching
it further (radix, etc.) was counter-productive.

> 1. how to list params:  (locale_ = locale)(throw_ = true) vs (locale_
> = locale, throw_ = true) vs ((locale_ = locale, throw_ = true))

It's pretty much "decided"... for now. :-) Simply because ((...)) looks very odd
and I personally do not want to give that syntax the user. Then, (,) (as I
understand) has its limitations and requires deploying Boost.Parameter macros
which I am not comfortable with. Then, the ()() chaining syntax is
standard/familiar, scales well and does not impose any limitations or typing
penalties. Sounds like a clear winner to me. The usual i-can-be-wrong disclaimer.

> 2. where to list params:  from(str, 0)(more stuff) vs from(str,
> 0).with(more stuff) vs (more stuff).from(str, 0)

When this discussion started (or rather re-started) I revisited the 'convert'
implementation and my design decisions. *I* am convinced that convert<TypeOut>
and even convert<TypeIn, TypeOut> do not work in general terms and the delayed
2-step specialization (1-st on the TypeOut via convert<TypeOut>, 2-nd on the
TypeIn via from()) is essential. Therefore, I *currently* feel that the
suggested (more stuff).from(str, 0) interface won't work. As for Rob's
from(str,0).with(more stuff) I do agree that it clears up whatever confusion
there might be and I am prepared to incorporate that if there is enough support
for it. I personally just can't help thinking that we are trying a bit too hard
spelling everything out -- it's not the trickiest of all interfaces (many Boost
components come to mind) and the seasoned users are unlikely to need 'with'. The
beginners will need to read the documentation anyway.

> 3. returning an int (well, whatever the To type is)

I'd love 'convert' to return TypeOut directly. I feel that it cannot. Have you
had a chance to read the documentation that is in the Vault with the 'convert'
implementation? There I tried to cover various scenarios. That said, I feel that
for simple cases 'convert' behaves *almost* like it returns TypeOut directly.
The only wrinkle was using the result in template functions like

template<class T> void foo();
foo(convert<int>::from(s));

For that there is

foo(convert<int>::from(s).value());
or
foo<int>(convert<int>::from(s));

> 4. use cases: function object, direct call, etc

I tried to cover the use-cases that I personally deploy and those that people
mentioned and I could think of in the document that comes with the
implementation (in the Vault). If you have some additional use-cases in mind,
I'll be happy to address and incorporate those as well.
 
> 5. ?

I'd encourage you to read the doc. and bring up whatever you feel not covered,
missing, incorrectly designed, etc. I am looking forward to your input.

V.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [convert] are you mixing default_value and error_value?

by Vladimir Batov-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> vicente.botet <vicente.botet <at> wanadoo.fr> writes:
> I have read the documentation and I think that you are mixing default
> value with error value.

I am not sure I can agree. In my book there is *no* separate default value.
There is only one value -- the conversion-failure (called default, error, etc.)
value.

> The fact that a
> type is not DefaultConstructible do not implies that the user
> wants to have an exception when the
> conversion fails. This are two orthogonal dimensions.

I think you are saying that "The fact that a type is not DefaultConstructible
does not mean that the user *does not* want to have an exception when the
conversion fails" because when the default/error value is provided, there is
*no* exception on failure.

And indeed, I strongly agree that these two issues -- the throwing behavior and
providing/not-providing the default/error value -- are indeed orthogonal. I am
very glad you mention that because IMHO it is a subtle but important issue that
is often missed or misunderstood.

> I think that for these non Default constructible types you can use
> a trait that gives you a default value for
> types not having a default constructor. E.g.
>
> template <typename T>
> struct default_value_trait {
>     static const T value=T();
> };
>
> template <>
> struct default_value_trait<direction> {
>     static const direction value=direction::up;
> };
>
> So now you don't need any more to pass the default value as
> parameter, and the following should compile
>
> direction dir = convert<direction>::from (str);  
>
> and could  throw if conversion fails after minor modification
> on the implementation.

Yes, it is an interesting approach and I like it as it allows to deploy throwing
'convert' uniformly for DefaultConstructible and NonDefaultConstructible types.
The only hesitation that pops to my mind is that I feel 'convert' is fairly
straightforward and needs to be used without much/any preparation. (That's how I
tend to use it anyway). That's why I was whining about the named parameters'
interface as it requires a round trip to the top of the file to add 'using'. If
lazy-me has to do the same for the default_value_trait<direction>
specialization, then I'll probably try avoiding that. On the other hand,
integration of a Type into the lexical_cast/convert framework does require some
preparation -- namely op>>() and op<<(). We could keep it for backward
compatibility but might offer a new trait-based way of integrating a Type into
the lexical_cast/convert framework. Like

template<>
struct convert_trait<Type>
{
}

where we might put anything related to the integration of the Type into the
convert framework. Is it too far-fetched? Thinking aloud really.

> I suppose you can reach the same effect with the error_value
> needed when the user want no_thow semantics.
>
> template <typename T>
> struct error_value_trait {
>     static const T value=T();
> };
>
> template <>
> struct error_value_trait<direction> {
>     static const direction value=direction::down;
> };
>
> So the following
>
> direction dir = convert<direction>::from (str)(_thows=false);  
>
> will return direction::down when conversion fails after
> some modification on the implementation

That feels over-engineered. Somehow I feel more comfortable with more explicit

direction dir = convert<direction>::from(str, direction::dn);  

> One more question raise now. Should the fact the conversion throws
> or not when failing be part of the
> function type or a function parameter?
>
> Do we need
>
> direction dir = convert<direction, no_thows<> >::from (str);  
>
> or
>
> direction dir = convert<direction>::from (str)(_thows=false);  

Yes, that's a fair question. I considered convert<Type, Throw> before and back
then it seemed that it was more flexible to configure the throwing behavior via
a parameter. Having convert<Type>::result played a role as well.

To me, in principle, there is no much difference between supplying a parameter
as a template or as an argument. So, I chose the one that looked less
restrictive and scaled better. Do you feel the template-based could do better?

> Resumein, I think these modifications are important,
> so the convert function can have always only the From
> parameter, and the throw semantics is preserved for non
> DefaultConstructible types.

>From my usage pattern I do not think I want "the convert function to always have
only the From parameter". In fact, truth to be told, for me it is the other way
around -- I *never* use the convert function with only the From parameter. :-) I
prefer having the failure value immediately visible as in the following (typical
for my usage) example:

int v = convert<int>::from(s, MAX_INT);
if (v == MAX_INT) conversion failed.

convert<direction>::result d = convert<direction>::from(s, direction::up);
if (!d) conversion failed.

That said, convert_trait seems tempting. What others think?

V.




_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [convert] Now with Boost.Parameter interface.

by Hartmut Kaiser :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> I've incorporated, uploaded to the Vault and started playing with the
> Boost.Parameter-based interface that Andrey Semashev was insisting from
> the set-go. And it is definitely growing on me and I like
>
>         int i = convert<int>::from(str, 0)(locale_ = new_locale)(throw_
> =
> true);
>
> instead of the original
>
>         int i = convert<int>::from(str, 0) >> new_locale >> dothrow;
>
> I think people generally did not like locales and dothrow behaving like
> manipulators.

Sorry if I'm late here. Either of both ways just feels wrong as not all of
the manipulators/parameters are of general use. The radix_ parameter
described elsewhere is a good example for a parameter applicable to string
<--> integer conversion only. It is highly confusing not to get a compile
time error while specifying a wrong parameter (a parameter not being
applicable for the type to convert to/from).

For instance, what is supposed to happen if I do:

    convert<double>::from(str, radix_ = 16)

?

The current approach in my view mixes things not belonging together. A
conversion library needs to keep apart data and formatting information. This
is not done here. Formatting and data type are spread over the whole
expression, making it very difficult to get things right.

I believe this is a strength of Spirit's approach, where data and formatting
are clearly separated. Applying a similar approach to convert would result
in:

    double d = convert::from(str, double_);
and
    std::string s = convert::to(d, double_);

where double_ is an example for a placeholder allowing to specify arbitrary
formats (remember, Spirit allows to build more complex formats/grammars out
of simpler ones, while providing all necessary primitive type conversions).
For instance, applying a different locale to this results in:

real_spec<double> locale_double(new_locale);

    double d = convert::from(str, locale_double);
and
    std::string s = convert::to(d, locale_double);

where real_spec (choose a different name, if you like) creates a new
placeholder encapsulating all formatting information needed to do the
conversion.

This has the additional advantage of providing a nicely extensible
framework. Any non-foreseeable formatting requirements are easily
customizable.


OTOH, general parameters applying directly to the conversion process (such
as throwing behavior or default values) are fine to be passed as additional
arguments. But care must be taken not to intermix this with formatting
related parameters (and yes, believe me or not, locales _are_ formatting
related). So I think the following would be ok:

    double d = convert::from(str, double_, default_ = 0.0);
and
    std::string s = convert::to(d, double_, throw_ = true);


BTW: this interface above is easily implementable on top of Spirit. It's
just a thin wrapper around existing functionality. And I already expressed
my opinion that any high level conversion library should be built on top of
Spirit - a proven, fast, reliable, versatile, and mature parser and
generator framework. Anything else leads to code duplication,
inconsistencies, implementation flaws, you name it. Converting a string of
digits into an integer might seem to be an easy task. But it's not. It's
tricky, error prone, and difficult to get correct _and_ fast at the same
time.

But all that is certainly purely IMHO.
Regards Hartmut


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [convert] Now with Boost.Parameter interface.

by Joel de Guzman-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hartmut Kaiser wrote:

>
> BTW: this interface above is easily implementable on top of Spirit. It's
> just a thin wrapper around existing functionality. And I already expressed
> my opinion that any high level conversion library should be built on top of
> Spirit - a proven, fast, reliable, versatile, and mature parser and
> generator framework. Anything else leads to code duplication,
> inconsistencies, implementation flaws, you name it. Converting a string of
> digits into an integer might seem to be an easy task. But it's not. It's
> tricky, error prone, and difficult to get correct _and_ fast at the same
> time.

I think the barrier to adoption is the size of the Spirit library and
its dependencies. For example, I'd be afraid to write a small library
that forces my users to depend on Proto, MPL, and Fusion too. That,
IMO, is too much to ask.

People might not be aware though that Spirit is very modular. The
numeric parsing/generating utilities are in fact just a couple of
small *independent* header files. It might be a good idea to
fully decouple them from Spirit into, say, Boost.Utilities.
This is becoming more pertinent now that more people are needing
them. Indeed, parsing and generating numbers is not easy. Make
no mistake.

Regards,
--
Joel de Guzman
http://www.boostpro.com
http://spirit.sf.net

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [convert] are you mixing default_value and error_value?

by Gottlob Frege :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, Jul 6, 2009 at 6:03 PM, Vladimir
Batov<vladimir.batov@...> wrote:

>> vicente.botet <vicente.botet <at> wanadoo.fr> writes:
>> I have read the documentation and I think that you are mixing default
>> value with error value.
>
> I am not sure I can agree. In my book there is *no* separate default value.
> There is only one value -- the conversion-failure (called default, error, etc.)
> value.
>
>> The fact that a
>> type is not DefaultConstructible do not implies that the user
>> wants to have an exception when the
>> conversion fails. This are two orthogonal dimensions.
>
> I think you are saying that "The fact that a type is not DefaultConstructible
> does not mean that the user *does not* want to have an exception when the
> conversion fails" because when the default/error value is provided, there is
> *no* exception on failure.
>
> And indeed, I strongly agree that these two issues -- the throwing behavior and
> providing/not-providing the default/error value -- are indeed orthogonal. I am
> very glad you mention that because IMHO it is a subtle but important issue that
> is often missed or misunderstood.
>

default and error are *mostly* orthogonal
default and DefaultConstructible are *mostly* orthogonal as well:

default and error:
- if I supply a default, then I do NOT expect an error
- if we did (as once suggested)
      int x = convert<int>::from(str, 0, &error);
  then I supply a default so that x is set to something, but still
want any error (warning?) info

default and DefaultConstructible:
- if the To type is NOT DefaultConstructible, then if I want a
default, I need to supply one
- if the To type IS DefaultConstructible, then I might STILL want to
pass in a default:
     int min  = convert<int>::from(minStr, 0); // get min or assume 0
     int max = convert<int>::from(maxStr, 100); // get max, else 100

so for a given To type:

if (To is DefaultConstructible)
{
    if (specific default requested)
    {
        int max = convert<int>::from(str, 100);
        // default supplied so no error
    }
    else
    {
         if (want the "class-defined" default)
         {
              // ie we want convert to default-construct the result if necessary

              int max = convert<int>::from(str, throw_ = false);
              // or ?
              int max = convert<int>::from(str);  // ie what's the
default for throw_?
              // or, of course
              int max = convert<int>::from(str, int());
         }
         else  // want errors
         {
              int m = convert<int>::from(str, throw_ = true);
              // or maybe
              int m = convert<int>::from(str, &error);
         }
    }
}
else // NOT DefaultConstructible
{
   struct NoDefCon
   {
       NoDefCon(int x, int y) { }
   };

   if (want specific default)
   {
       // supply default explicitly
       // same form as other specific-default case above
       NoDefCon ndc = convert<NoDefCon>::from(str, NoDefCon(1, 3));
   }
   else
   {
       // don't want a specific default?
       // no choice but to throw:
       NoDefCon ndc = convert<NoDefCon>::from(str);
   }
}

If all the concepts were completely orthogonal, we'd have a few more if blocks.


>> I think that for these non Default constructible types you can use
>> a trait that gives you a default value for
>> types not having a default constructor. E.g.
>>
>> template <typename T>
>> struct default_value_trait {
>>     static const T value=T();
>> };
>>
>> template <>
>> struct default_value_trait<direction> {
>>     static const direction value=direction::up;
>> };
>>
>> So now you don't need any more to pass the default value as
>> parameter, and the following should compile
>>
>> direction dir = convert<direction>::from (str);
>>
>> and could  throw if conversion fails after minor modification
>> on the implementation.
>
> Yes, it is an interesting approach and I like it as it allows to deploy throwing
> 'convert' uniformly for DefaultConstructible and NonDefaultConstructible types.
> The only hesitation that pops to my mind is that I feel 'convert' is fairly
> straightforward and needs to be used without much/any preparation. (That's how I
> tend to use it anyway). That's why I was whining about the named parameters'
> interface as it requires a round trip to the top of the file to add 'using'. If
> lazy-me has to do the same for the default_value_trait<direction>
> specialization, then I'll probably try avoiding that. On the other hand,
> integration of a Type into the lexical_cast/convert framework does require some
> preparation -- namely op>>() and op<<(). We could keep it for backward
> compatibility but might offer a new trait-based way of integrating a Type into
> the lexical_cast/convert framework. Like
>
> template<>
> struct convert_trait<Type>
> {
> }
>
> where we might put anything related to the integration of the Type into the
> convert framework. Is it too far-fetched? Thinking aloud really.
>
>> I suppose you can reach the same effect with the error_value
>> needed when the user want no_thow semantics.
>>
>> template <typename T>
>> struct error_value_trait {
>>     static const T value=T();
>> };
>>
>> template <>
>> struct error_value_trait<direction> {
>>     static const direction value=direction::down;
>> };
>>
>> So the following
>>
>> direction dir = convert<direction>::from (str)(_thows=false);
>>
>> will return direction::down when conversion fails after
>> some modification on the implementation
>
> That feels over-engineered. Somehow I feel more comfortable with more explicit
>
> direction dir = convert<direction>::from(str, direction::dn);
>
>> One more question raise now. Should the fact the conversion throws
>> or not when failing be part of the
>> function type or a function parameter?
>>
>> Do we need
>>
>> direction dir = convert<direction, no_thows<> >::from (str);
>>
>> or
>>
>> direction dir = convert<direction>::from (str)(_thows=false);
>
> Yes, that's a fair question. I considered convert<Type, Throw> before and back
> then it seemed that it was more flexible to configure the throwing behavior via
> a parameter. Having convert<Type>::result played a role as well.
>
> To me, in principle, there is no much difference between supplying a parameter
> as a template or as an argument. So, I chose the one that looked less
> restrictive and scaled better. Do you feel the template-based could do better?
>
>> Resumein, I think these modifications are important,
>> so the convert function can have always only the From
>> parameter, and the throw semantics is preserved for non
>> DefaultConstructible types.
>
> >From my usage pattern I do not think I want "the convert function to always have
> only the From parameter". In fact, truth to be told, for me it is the other way
> around -- I *never* use the convert function with only the From parameter. :-) I
> prefer having the failure value immediately visible as in the following (typical
> for my usage) example:
>
> int v = convert<int>::from(s, MAX_INT);
> if (v == MAX_INT) conversion failed.
>
> convert<direction>::result d = convert<direction>::from(s, direction::up);
> if (!d) conversion failed.
>
> That said, convert_trait seems tempting. What others think?
>
> V.
>

Overall, I think defaults are not class-level decisions, but
call-level choices.  Like the min/max case.  One convert call might
use 0 as the default, the other 100.

I DO think that an error_value, IS (typically) a class-level trait.
Well, maybe not for ints.  Sometimes, in one context, 0 might be a
good error value, sometimes -1, etc.  Often it may be the case that
need a stronger type than 'int', but that doesn't always happen in
pratice.  Could always pass in the trait:

   int x = convert<int, my_convert_traits>::from(str);

with a default of convert_trait<To> if not specified.

Basically, I'm not convinced about the traits...

Tony
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: [convert] are you mixing default_value and error_value?

by Vicente Botet Escriba :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


----- Original Message -----
From: "Vladimir Batov" <vladimir.batov@...>
To: <boost@...>
Sent: Tuesday, July 07, 2009 12:03 AM
Subject: Re: [boost][convert] are you mixing default_value and error_value?


>
>> vicente.botet <vicente.botet <at> wanadoo.fr> writes:
>> I have read the documentation and I think that you are mixing default
>> value with error value.
>
> I am not sure I can agree. In my book there is *no* separate default value.
> There is only one value -- the conversion-failure (called default, error, etc.)
> value.
>
>> The fact that a
>> type is not DefaultConstructible do not implies that the user
>> wants to have an exception when the
>> conversion fails. This are two orthogonal dimensions.
>
> I think you are saying that "The fact that a type is not DefaultConstructible
> does not mean that the user *does not* want to have an exception when the
> conversion fails" because when the default/error value is provided, there is
> *no* exception on failure.

Yes, this is what I wanted to say. On the case of the direction class, you are forced to give an *initial value* because direction is not default constructible, but with your interface we can't have an exception in this case. Is for this reason I say you are mixin both.
 
> And indeed, I strongly agree that these two issues -- the throwing behavior and
> providing/not-providing the default/error value -- are indeed orthogonal. I am
> very glad you mention that because IMHO it is a subtle but important issue that
> is often missed or misunderstood.

So, do you plan to separate them?
 

>> I think that for these non Default constructible types you can use
>> a trait that gives you a default value for
>> types not having a default constructor. E.g.
>>
>> template <typename T>
>> struct default_value_trait {
>>     static const T value=T();
>> };
>>
>> template <>
>> struct default_value_trait<direction> {
>>     static const direction value=direction::up;
>> };
>>
>> So now you don't need any more to pass the default value as
>> parameter, and the following should compile
>>
>> direction dir = convert<direction>::from (str);  
>>
>> and could  throw if conversion fails after minor modification
>> on the implementation.
>
> Yes, it is an interesting approach and I like it as it allows to deploy throwing
> 'convert' uniformly for DefaultConstructible and NonDefaultConstructible types.
> The only hesitation that pops to my mind is that I feel 'convert' is fairly
> straightforward and needs to be used without much/any preparation. (That's how I
> tend to use it anyway). That's why I was whining about the named parameters'
> interface as it requires a round trip to the top of the file to add 'using'. If
> lazy-me has to do the same for the default_value_trait<direction>
> specialization, then I'll probably try avoiding that.

This is surely because you are mixing the returned value when a failure occur and the initial value when the class is not default convertible.

> On the other hand,
> integration of a Type into the lexical_cast/convert framework does require some
> preparation -- namely op>>() and op<<().  We could keep it for backward
> compatibility but might offer a new trait-based way of integrating a Type into
> the lexical_cast/convert framework. Like
>
> template<>
> struct convert_trait<Type>
> {
> }
>
> where we might put anything related to the integration of the Type into the
> convert framework. Is it too far-fetched? Thinking aloud really.

Why not?
 

>> I suppose you can reach the same effect with the error_value
>> needed when the user want no_thow semantics.
>>
>> template <typename T>
>> struct error_value_trait {
>>     static const T value=T();
>> };
>>
>> template <>
>> struct error_value_trait<direction> {
>>     static const direction value=direction::down;
>> };
>>
>> So the following
>>
>> direction dir = convert<direction>::from (str)(_thows=false);  
>>
>> will return direction::down when conversion fails after
>> some modification on the implementation
>
> That feels over-engineered. Somehow I feel more comfortable with more explicit
>
> direction dir = convert<direction>::from(str, direction::dn);  

You are right the failure returned value should be given at the call. What about  passing it statically
    direction dir = convert<direction, no_throws<direction::dn> >(str);  
or dynamically
    direction dir = convert<direction>(str, (_no_throws=direction::dn));  

>> One more question raise now. Should the fact the conversion throws
>> or not when failing be part of the
>> function type or a function parameter?
>>
>> Do we need
>>
>> direction dir = convert<direction, no_thows<> >::from (str);  
>>
>> or
>>
>> direction dir = convert<direction>::from (str)(_thows=false);  
>
> Yes, that's a fair question. I considered convert<Type, Throw> before and back
> then it seemed that it was more flexible to configure the throwing behavior via
> a parameter.

Have you considered to return failure setting errno? How can your current interface be adapted to this use case?

With a coverter template parameter you can do something like: statically
    direction dir = convert<direction, set_errno<EINVALID> >(str);  
or dynamicaly
    direction dir = convert<direction>(str, (_set_errno=EINVALID));  

> Having convert<Type>::result played a role as well.

Have you considered to convert returns just a pair<T, bool> or optional<T>? How can your current interface be adapted to these use cases?

With a template parameter you can do something like

pair<direction, bool> dirp = convert<direction, return_pair >(str);  
optional<direction> opt_dir = convert<direction, return_optional >(str);  
or
pair<direction, bool> dirp = convert<direction>(str, _return_pair);  
optional<direction> opt_dir = convert<direction>(str, _return_optional);  
 
> To me, in principle, there is no much difference between supplying a parameter
> as a template or as an argument. So, I chose the one that looked less
> restrictive and scaled better. Do you feel the template-based could do better?

Templating the convert function with a converter parameter allows to have different return types that depend on the converter parameter.

A model of converter is the functor class realizing the conversion using the conversion parameters
template <typename To>
struct converter {
    typedef related to To result_type;
    converter();
    converter(converter_parameters<To> const&);
    template <typenam From> result_type operator()(From);
};

The convert function can return the out type  (To) instead of the internal converter which is implicitly convertible to the To type.

template <typename To, typename Converter, typename From >
Converter::retult_type convert(From f, Converter const&cv) {
    return cv(f);
}
 
>> Resumein, I think these modifications are important,
>> so the convert function can have always only the From
>> parameter, and the throw semantics is preserved for non
>> DefaultConstructible types.

Rectification, the convert function can have two parameters, first the From type and second the converter (parameters). The converter class must define operator()(From).
 
>>From my usage pattern I do not think I want "the convert function to always have
> only the From parameter". In fact, truth to be told, for me it is the other way
> around -- I *never* use the convert function with only the From parameter. :-) I
> prefer having the failure value immediately visible as in the following (typical
> for my usage) example:
>
> int v = convert<int>::from(s, MAX_INT);
> if (v == MAX_INT) conversion failed.

What about
    int v = convert<int>(s, _no_thows=MAX_INT);
    if (v == MAX_INT) conversion failed.
 
> convert<direction>::result d = convert<direction>::from(s, direction::up);
> if (!d) conversion failed.

And

optional<direction> d = convert<direction>(str, _return_optional );  
if (!d) conversion failed.
 
> That said, convert_trait seems tempting. What others think?

We can see

_no_thows=MAX_INT
_return_pair
_return_optional

and the other parameters as elements of a DSL configuring the conversion.

This view of the convert function with a converter parameter joins a little bit the one proposed by Hartmut in a recent post. What others think?

Best,
Vicente

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
< Prev | 1 - 2 - 3 | Next >