C++11 provides two type trait template classes: std::is_integer
and std::is_integral
. However, I cannot tell the differences between them.
There is no type T
that has different results for std::is_integral<T>::value
and std::numeric_limits<T>::is_integer
. To quote the draft Standard:
3.9.1 Fundamental types [basic.fundamental]
7 Types bool, char, char16_t, char32_t, wchar_t, and the signed and unsigned integer types are collectively called integral types. A synonym for integral type is integer type.[...]
18.3.2.4 numeric_limits members [numeric.limits.members]
static constexpr bool is_integer;
17 True if the type is integer.
20.9.4.1 Primary type categories [meta.unary.cat] (table 47)
template <class T> struct is_integral;
T is an integral type (3.9.1)
std::is_integral_v<T>
will only return true for built-in integers.
The standard allows std::numeric_limits<T>::is_integer
to be specialized and return true for custom integral types like boost::multiprecion::cpp_int
.
std::is_integer<T>
does not exist.
That being said, std::numeric_limits<T>::is_integer
does exist.
I'm not aware of any significant difference between std::numeric_limits<T>::is_integer
and std::is_integral<T>
. The latter was designed much later and became standard in C++11, whereas the former was introduced in C++98.
std::is_integral<T>
and std::numeric_limits<T>::is_integer
are NOT the same. E.g. boost::multiprecision
big ints are treated differently.
This is from a corresponding issue:
is_integral
returns information about the nature of the type and is true only for "native" integer types, it should never be true for class types. Which is to sayis_integer
andis_class
are mutually exclusive.
numeric_limits
on the other hand returns information on the behaviour of a type - whether it models a particular concept if you will - and so should be specialized for UDT's. Note that specializingis_integer
for UDTs would break code, sinceis_integer
implies that a lot of other things are also true like trivial move/copy/init etc.
The difference is that std::is_integral<T>
will only recognize decimal integers including bool
char
char16_t
char32_t
wchar_t
short
int
long
long long
. While std::numeric_limits<T>::is_integer
will recognize all of those aswell as float
double
. Look at these two pages for more information: is_integer, is_integral