
Stewart, Robert wrote:
Vicente BOTET wrote:
De : "Vladimir Batov"
"Stewart, Robert" wrote Maybe to avoid the temptation of pairing up we could simplify (at least from the user perspectives) down to:
1. T convert_cast(S) 2. T convert_cast(S, T, throw_t =nothrow) I don't see why (2) the user could want to throw when is giving a fallback. So the throw_t =nothrow is not needed.
That's the non-DefaultConstructible, no-sentinel use case:
struct example { example(int); };
To get an exception on conversion failure, one writes:
example const e(convert_cast<example>("1")); // exception
However, without the default_value CP, that fails because example is non-DefaultConstructible.
One can avoid the exception by providing a fallback value:
example const e(convert_cast<example>("1", 3)); // no exception
(I'm assuming the fallback value can be of type U implicitly convertible to T.)
In that case, e == example(3).
But if one wants an exception to indicate conversion failure, an initial value is needed and the desire for an exception must be noted:
example const e(convert_cast<example>("1", 3, throw_)); // exception
Sorry if I'm just being dense, but if the above throws, the default value is never used, so why supply it?
Obviously, with your default_value CP, the second argument isn't needed for the last use case:
template <> default_value<example> { static example apply() { return example(3); } };
example const e(convert_cast<example>("1")); // exception
So it's really just the no-default function that needs to be told to throw or return an optional. Jeff