Why are the numbers 10 to refer to the integer type 0?

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"; } 

exits

19
0

I would expect std::uint64_t& to have the same meaning as std::uint64_t : is there a reason for this mismatch?

+5
source share
3 answers

18.3.2.1/2:

Specializations must be provided for each arithmetic type, as a floating point and integer, including bool. The is_specialized member must be true for all such numeric_limits specializations.

So, we know that specializations will exist for these types without reference. Then 18.3.2.3/1:

The default numeric_limits template must have all members, but with 0 or false values.

I suspect this was done because you can always static_assert on is_specialized to force compilation, but there might be some kind of template application where 0 will be the default default for one or more constraints. If you want to be able to test links, just run it via std::remove_reference .

I'm not sure if the specialization of numeric_limits is legal for your own types. The standard in 18.3.2.1/4 states:

Non-arithmetic standard types, such as complex (26.4.2), should not be specialized.

I personally read this qute as "the standard will not provide specializations for non-arithmetic standard libray types, but it is completely legal for specialization for a user type." You can read it just as easily as completely disallowing any specializations not provided.

+2
source

The uint64& type is a reference, so it is not one of the arithmetic types for which the numeric_limits pattern should be used.

For any types other than certain arithmetic types, the default definition is used, which contains:

 static const int digits10 = 0; 

Link: http://www.cplusplus.com/reference/limits/numeric_limits/

+1
source

std::numeric_limits is expected to be specialized for basic arithmetic data types (integers and floating points). A link to any species does not belong to them and why an unspecialized template was selected that has all its members in false ( 0 ).

I would expect std :: uint64_t & to have the same meaning as std :: uint64_t: Is there any reason for this mismatch?

Although std::uint64_t is an arithmetic type, std::uint64_t& is a composite type and has a different meaning. You have several options:

  • Always use the base type when deleting a link, pointer, or both.
  • static_assert( is_arithmetic<> )
  • check std::numeric_limits<T>::is_specialized
0
source

Source: https://habr.com/ru/post/1216612/


All Articles