Boost logo

Boost :

Subject: Re: [boost] [review] string convert
From: Gordon Woodhull (gordon_at_[hidden])
Date: 2011-05-04 11:51:47


On May 4, 2011, at 11:32 AM, Phil Endecott wrote:

> Gordon Woodhull wrote:
>> int i = convert_cast<int>(s); // default behavior: might throw
>> optional<int> i = convert_cast<int>(s, use_optional_instead_of_throwing_);
>> int i = convert_cast<int>(s, 17); // won't throw; can't tell if conversion successful
>
> Why do you prefer the tags rather than just adding the error policy to the name?

>
> And why do you prefer template specialisation rather than just adding the type to the name?
>
> (Keep It Simple.)

I am fine either way. I was just taking the thought to its conclusion.

I think if there end up being a lot of behaviors and they interact, then overloads are better.

>
> int i = must_parse_int(s); // Personally I use "must" to mean "else throw", but I
> // wouldn't want to impose that on anyone else.
> optional<int> i = try_parse_int(s); // I've never used optional<> here, but I tend to
> // write try_* for things that return a boolean to
> // indicate success.
> int i = parse_int_with_default(s, 17);

Decent suggestions.

> But per my last posts, anyone can easily write those in whatever style they want, if they
> have the core function, e.g.
>
> template <typename ITER>
> void parse_int(ITER begin, ITER end, int& i, bool& success)
> {
> ....
> }
>
> int must_parse_int(std::string s)
> {
> int i; bool success;
> parse_int(s.begin(),s.end(),i,success);
> if (!success) throw ParseError();
> return i;
> }
>
> optional<int> try_parse_int(std::string s)
> {
> int i; bool success;
> parse_int(s.begin(),s.end(),i,success);
> return success ? i : optional<int>();
> }
>
> int parse_int_with_default(std::string s, int def)
> {
> int i; bool success;
> parse_int(s.begin(),s.end(),i,success);
> return success ? i : def;
> }

Right, I am thinking something like your parse_int combined with Vicente's two-type customization method.

> (I'm confused by the following, which look pointless; have I missed something?)

I think you have. But I'll go through it one last time.

>> int i = convert_cast<int>(s, 17, throw_even_though_i_specified_a_failback_);
>> optional<int> i = convert_cast<int>(s, 17, use_optional_instead_of_throwing_);

These are for nondefaultable types. I probably shouldn't have used int in my example; what's a well-known example of a nondefaultable type? You must supply an initial value, but you don't want to use it.

Pretty rare, but if you're in that case, you'll be annoyed if you don't have these. That's why they're the ones which still take ugly extra tags even after either Barend's or Matt's simplifications.

>> pair<bool,int> i = convert_cast<int>(s, 17, fallback_and_report_success_);

Please read my 11:39am message to Jeff.

Cheers,
Gordon


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