Boost logo

Boost :

Subject: Re: [boost] [review] string convert
From: Stewart, Robert (Robert.Stewart_at_[hidden])
Date: 2011-05-05 07:48:30

Vladimir Batov wrote:

[This post is a little long; I summarize my suggestion at the end]

> The question of the return type remains -- returning simply T
> does not cut it for me. I need two things returned -- the
> value (conversion result or fallback) and success/failure.
> Unless we are prepared to discard my major use-case altogether
> (which would not be nice) we seem to have to have
> convert<T>::result convert<T>::from(...)
> or
> std::pair<optional<T>, bool> convert_to<T>(...)

I forgot your use case at first, but I think I recall it now. I'll discuss it below.

In another post, I offered the following interface:

> 1. T convert_cast<T,S>(S)
> 2. T convert_cast<T,S>(S, T)
> 3. T convert_cast<T,S>(S, T, nothrow_t)
> 4. optional<T> try_convert_cast<T,S>(S)
> 5. optional<T> try_convert_cast<T,S>(S, T)
> In 1, the result valid unless there's an exception. It doesn't
> work for non-DefaultConstructible UDTs.
> In 2, the result is always valid since it never throws. It
> works for non-DefaultConstructible UDTs, but not for types
> without a suitable fallback value.
> In 3, the result is valid unless there's an exception. 2 and 3
> could be merged, but keeping them distinct is probably more
> efficient and should be easier to document.
> In 4 and 5, the optional is set iff the conversion succeeds.
> 4 is useful for built-in types and DefaultConstructible UDTs.
> 5 is useful for all types.
> Arguably, "try_convert_cast" wants a better name.

Your use case is the following, right?

optional<int> o(try_convert_cast<int>(str));
int i;
if (!o)
   std::cout << "using fallback\n";
   i = fallback;
   i = o.get();

That's clearly inconvenient and 5 doesn't apply because the optional won't be set if the conversion fails. To address such inconvenience, you offered convert<T>::result and pair<optional<T>,bool> has been suggested. Isn't optional redundant in the latter? Consider this:

pair<int,bool> p(something<int>(str, fallback));
if (!p.second)
   std::cout << "using fallback\n";
int const i(p.first);

That's a straightforward use of pair and, I think, addresses everything. If the conversion fails, p.second is false, but p.first == fallback. If the conversion succeeds, p.second is true and p.first holds the conversion result. If the second argument to something() was not truly a fallback, doesn't p.second still provide the necessary information?

I noted one missing use case:

> What's missing, then, is getting an exception when a conversion
> to a non-DefaultConstructible UDT or a type with no fallback
> value fails. That is, a variant of 2 that throws on conversion
> failure.

Possibly, that would just mean:

2a. T convert_cast<T, S>(S, T, throw_t)

However, it's also possible to state that 2 always throws on failure because 3 can be used to force the T argument to be a fallback. That would be more consistent with the difference between 4 and 5, though less convenient for the fallback-without-exception use case which is, arguably, more common than the non-DefaultConstructible-type-with-exception use case (2, as presented above).

If we use Vicente's default_value customization point, however, things could be interpreted a little differently:

a) T convert_cast<T,S>(S)
b) T convert_cast<T,S>(S, T)
c) optional<T> try_convert_cast<T,S>(S)
d) optional<T> try_convert_cast<T,S>(S, T)

a) Uses default_value<T>, if needed, and throws on conversion failure.

b) Conversion failure implies returning the second argument's value.

c) Uses default_value<T>, if needed, and the return value is not set on conversion failure. This still needs a better name.

d) Conversion failure implies returning the second argument's value. This still needs a better name.

Given the relative rarity of types that need a special "default" value, and the fact that a compilation error on a line in the primary specialization of default_value can lead the library user to a comment that explains the need to specialize it for T, the regularity of a-d is compelling.

Three things are missing from a-d. One is formatting control. However, that can be done through extra arguments as suggested in various other posts. It may be that there would even be overloads of a-d that take the additional arguments in order to streamline the simpler cases.

Another thing missing from a-d is the function object you had in convert<T>::converter<S>, IIRC. Is there any reason that cannot just be captured by converter<T,S>? For simplicity of customizing the library, I'd even expect that a-d would use a converter<T,S>.

Finally, the function to address your use case is missing. It needs a suitable name, too.

e) pair<T,int> something<T,S>(S, T)

Summarizing, then:

 - default_value<T> customization point
 - converter<T,S> customization point; main logic
 - T convert_cast<T,S>(S, formatting = none); can throw
 - T convert_cast<T,S>(S, T, formatting = none)
 - optional<T> name_me_1<T,S>(S, formatting = none)
 - optional<T> name_me_1<T,S>(S, T, formatting = none)
 - pair<T,int> name_me_2<T,S>(S, T, formatting = none)

Note that the T argument for convert_cast<T,S>(S, T, formatting) is non-deducible in order to require specifying T in each call. Since the name_me_1 and name_me_2 names are not expected to end with "_cast," the T arguments may be deducible.

Rob Stewart robert.stewart_at_[hidden]
Software Engineer using std::disclaimer;
Dev Tools & Components
Susquehanna International Group, LLP

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.

Boost list run by bdawes at, gregod at, cpdaniel at, john at