Boost logo

Boost :

Subject: Re: [boost] [review] string convert
From: Matt Chambers (matt.chambers42_at_[hidden])
Date: 2011-05-04 09:57:50


On 5/4/2011 8:01 AM, Gordon Woodhull wrote:
> So, here's something complete (?) for people to rip apart:
>
> 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
> 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_);
> pair<bool,int> i = convert_cast<int>(s, 17, fallback_and_report_success_);
>
> I am not concerned with names, just with syntax. So I'm using "convert_cast" although I actually don't care what it's called, and I have some very ugly very descriptive tag values with distinct types to trigger different overloads, which might be abbreviated dont_throw_, do_throw_, and, um, tell_fallback_ or something.
>
> All would also accept extra manip_/format_= and locale_ arguments as in Vladimir's proposal, except they have to be appended to the first parameter list because of the "no proxies" requirement.
>
> Doesn't this now cover all the functionality we've been talking about?
>
> The 5th and 6th forms cover nondefaultable types / types with no sentinel value, and Vladimir's "print a warning if failing back" use-case.
>
> You mention noncopyable types but I'm not able to find any reference to that in the documentation or in previous discussion. I don't see how the value can be non-copyable since it's being returned by the function.
>
> I'd actually prefer the behavior flags were put in the template parameters, because they affect the return type, but that would be tricky because of the defaulted Destination type. (I don't think it's impossible, but it might be messy.)
>
> Maybe just having more functions would be simpler; I'm just taking an idea to its conclusion.
>
I definitely could do without the tags to pick an overload. I'd much rather have
the try_ prefix. So:

int i = convert_cast<int>(s); // default behavior: might throw
int i = convert_cast<int>(s, 17); // won't throw; can't tell if conversion
successful; but how often do people actually care about that if they're
providing a fallback value? it's still very practical and useful!
optional<int> i = try_convert_cast<int>(s); // won't throw; specialized version
of optional is not necessary since there's no fallback value
convert<int>::result i = try_convert_cast<int>(s, 17); // won't throw;
specialized version of optional is necessary to detect failure

// I'd get rid of these:
//int i = convert_cast<int>(s, 17, throw_even_though_i_specified_a_failback_);
// what's the purpose of this overload?
//optional<int> i = try_convert_cast<int>(s, 17); // this doesn't allow checking
for failure, so there's not much point
//pair<bool,int> i = convert_cast<int>(s, 17, fallback_and_report_success_); //
it's burning my eyes

>> Finding the right prefix for "_cast" will be a challenge.
> Sigh, another naming debate. (Naming is important but so difficult!) It does seem like the direction that *_cast<>() is clearer to people than convert<>()
>
> I also like as<>() :-) but somehow I don't think that'll generate consensus.
The first overload is a drop-in replacement for lexical_cast as far as I'm
concerned (even with additional arguments for locale and manipulators). If it
can pass all the lexical_cast tests, what's the harm?

-Matt


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