Boost logo

Boost :

Subject: Re: [boost] Formal Review Request: Boost.Convert
From: Vladimir Batov (batov_at_[hidden])
Date: 2009-02-23 23:36:58


> 1. Be able to provide a default value w/o type deducing being a problem.
> (ie: making the interface unclear)
> 2. Have the same interface when used as a functor.
> 3. Be very explicit and clear about if you're getting throwing behavior
> or defaulting behavior.

I believe we achieved thses goals with

int i = convert<string, int>(str);
int i = convert_to<int>(str);
int i = convert_from(str, -1);

See below.

>> // get "5" converted to int (throw on error)
>> int i = convert_to<int>("5")(throw_t());
>
> So could I do the following?
>
> vector<string> s;
> vector<int> i;
> transform (s.begin(), s.end(), back_inserter(i), convert_to<int,
> string>(throw_t()));

Pretty much. You can do the following

transform (
    s.begin(),
    s.end(),
    back_inserter(i),
    convert<int, string>(string(), -1)
>> throw_t() >> std::hex);

I.e. get throwing hex-formatting behavior.

>> // get "-1" converted to unsigned or else 0
>> unsigned u = convert_to<unsigned>("-1", 0);
>
> In this case <unsigned> isn't necessary, type deducing kicks in and we
> could just as well write:
> unsigned u = convert_to("-1", 0);

No, it won't work. 'convert_to' olny takes one argument and requires
explicit TypeTo:

unsigned i = convert_to(str).

'convert_from' does deduce both but I do not think there is confusion here:

unsigned u = convert_from("-1", 0);

> Which reads to me as "convert to -1 from 0".

As you can see it reads convert *from* "-1" string.

> And if we change "convert_to" to "convert" it becomes even more
> confusing.

I am not sure I follow this. Which part of the below do you find confusing?

unsigned u = convert<string, unsigned>("-1", 0);

>> // get "0xff" converted to int using as_hex functor
>> int i = convert_to<int>("0xff") >> std::hex;
>
> I thought operator>>() returns an istream? If there's precedent somewhere
> where it doesn't return an istream, forgive my ignorance please.

As far as I am concerned, op>>() returns whatever we'd like it to return.
IMHO it certainly is not the property of std::streams. You could have a look
at std::bitset. I am sure we can find many more examples.

> But given that interface, what does the following mean?
>
> int a, b, c;
> string d;
> int i = convert_to<int>("0xff") >> std::hex >> a >> b >> c >> d;

It surely looks gibberish to me. I am not sure about older version but with
the latest version I do not believe it will compile.

> I'm not married to my interface either, I was mainly just using this
> discussion as a sounding board. I'd like to see a really nice interface
> come out of it that addresses the points I made:
>
> 1. Be able to provide a default value w/o type deducing being a problem.
> (ie: making the interface unclear)

Do you find the following satisfactory or still have concerns:

int i = convert<string, int>(str);
int i = convert_to<int>(str);
int i = convert_from(str, -1);

> 2. Have the same interface when used as a functor.

How about this:

transform (
    s.begin(),
    s.end(),
    back_inserter(i),
    convert<int, string>(string(), -1)
>> throw_t() >> std::hex);

> 3. Be very explicit and clear about if you're getting throwing behavior
> or defaulting behavior.

Currently it is like this -- you provide a default, you get the defaulting
behavior; you do *not* provide a default, you get the throwing behavior. Do
you think it is sufficient? Still, we could do

int i = convert<string, int, throw_t::yes>(str);

It'd make the implementation leaner as well. But I suspect people won't like
it.

Best,
V.


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