The following code:
#include <iostream>
#include <limits>
#include <cstdint>
int main()
{
std::cout << std::numeric_limits<std::uint64_t>::digits10 << "\n"
<< std::numeric_limits<std::uint64_t&>::digits10 << "\n";
}
outputs
19
0
I would expect std::uint64_t&
to have same value as std::uint64_t
: Is there a reason for this discrepancy?
18.3.2.1/2:
Specializations shall be provided for each arithmetic type, both floating point and integer, including bool. The member is_specialized shall be true for all such specializations of numeric_limits.
So we know that specializations will exist for for these non-reference types. Then 18.3.2.3/1:
The default numeric_limits template shall have all members, but with 0 or false values.
I suspect it was done this way because you can always static_assert on is_specialized
to force a compile error, but there could possibly be some template application where 0 would be an ok default value for one or more of the limits. If you want to be able to test references just run it through std::remove_reference
.
I'm not sure if it's legal to specialize numeric_limits
for your own types. The standard in 18.3.2.1/4 says:
Non-arithmetic standard types, such as complex (26.4.2), shall not have specializations.
I personally read this qute as "the standard will not provide specializations for non-arithmetic standard libray types, but it's perfectly legal to specialize for a user type". You could just as easily read this as totally forbidding any non-provided specializations.
The type uint64&
is a reference, so it's not one of the arithmetic types that the numeric_limits
template should be used for.
For any other types than the arithmetic types defined, the default definition is used which contains:
static const int digits10 = 0;
Reference: http://www.cplusplus.com/reference/limits/numeric_limits/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With