[Development] Improving toInt, toLong, etc.

Matthew Woehlke mw_triad at users.sourceforge.net
Tue Feb 4 22:33:28 CET 2014


On 2014-02-04 15:07, Thiago Macieira wrote:
> Em ter 04 fev 2014, às 13:37:44, Matthew Woehlke escreveu:
>> Yeah, I'm not entirely on board with the whole "check the result or your
>> program dies" idea. Qt doesn't do that now; I definitely don't feel like
>> it needs to be added. (I guess QOptional will still assert though if you
>> call value() and it is disengaged? Just like a container would when
>> using operator[] on a non-existing index?)
>
> There are two possibilities:
> 1) operator T() asserts if it's disengaged
> 2) operator T() returns a default-constructed type if it's disengaged
>
> Or we don't have an operator T() at all. A T &operator*() might be better,
> which must assert. I haven't looked at the std::optional proposal yet.

Regardless of what the proposal says, I'd vote to avoid operator T(). I 
think you have to anyway in QOptional<bool>, and not having an operator 
T() avoids needing to specialize over bool (which is good both from an 
implementation standpoint and also for API consistency).

Personally, I'd also incline to value() asserting if disengaged. For 
one, this way you can have a non-const that returns a T&.

I think asserting is consistent with e.g. Qt's container classes?

> I'd like to keep value(const T &invalidAs) never asserting, like other methods
> work already.

In the signature above (a default explicitly provided in case the 
QOptional is disengaged), that's sort-of the point of the default :-).

> operator T() implies no operator bool().

I'd rather have implicit use in a conditional expression evaluate if the 
QOptional is engaged. Also, operator bool() is required to do e.g.:

   if (auto result = s.toInt(...))

I also like that the operator bool() / operator*() API, as you also 
noted, resembles a pointer; I think that's a good thing.

>>> That means the front-end function would be:
>>>    template <typename T> QOptional<T> toIntegral(int base = 10, int *endpos
>>>    = 0) // plus the enableif integral type
>>
>> Consider 'toNumber' so that it can take either integral or floating
>> point types?
>
> Floating point doesn't have a base, so it's a different type.

It should :P. If you save me from having to write my own base-16 string 
to double conversion, I will be happy :-). (I haven't gotten to the 
point of needing it in the relevant project, but at some point I am 
going to be writing a file format, and - in order to avoid data loss in 
round trips from text to binary - it *is* going to encode doubles in 
base-16.)

Also note that C99 specifies that printf accepts '%a' for the other 
direction; floating point to base-16 text.

Even if you don't add alternate-base support for floating point, you can 
still provide different overloads for floating point specializations 
versus integral specializations.

> I can add a
> toNumber() whose integral specialisations call toIntegral(), though.

That works; no objection to having those two spellings for the same 
underlying functionality.

-- 
Matthew




More information about the Development mailing list