'Why is "std::is_pointer<std::nullptr_t>::value" equal to false?
I read about std::is_pointer
in C++.
Then I wrote the program and check whether T
is a pointer type or not using std::is_pointer
.
#include <iostream>
int main()
{
std::cout<<std::boolalpha;
std::cout<<"char : " <<std::is_pointer<char>::value<<std::endl; // OK
std::cout<<"char * : "<<std::is_pointer<char *>::value<<std::endl; // OK
std::cout<<"char ** : "<<std::is_pointer<char **>::value<<std::endl; // OK
std::cout<<"char *** : "<<std::is_pointer<char ***>::value<<std::endl; // OK
std::cout<<"std::nullptr_t : "<<std::is_pointer<std::nullptr_t>::value<<std::endl; // Not ok, Why false??
}
Output : [Wandbox Demo]
char : false
char * : true
char ** : true
char *** : true
std::nullptr_t : false
Why is std::is_pointer<std::nullptr_t>::value
equal to false
?
Solution 1:[1]
Because std::nullptr_t
is not a pointer type. And is_pointer
only evaluates to true
for pointer types.
nullptr_t
is convertible to a pointer, but it isn't a pointer. Indeed, nullptr_t
is not a class type, integral, floating-point, enumerator, or any kind of type other than is_null_pointer
type. It has its own unique classification in the categorization of types.
Solution 2:[2]
Because it's not a pointer type. It's a distinct type that is implicitly convertible to any pointer type.
As the note in [lex.nullptr] summarizes:
The pointer literal is the keyword nullptr. It is a prvalue of type std?::?nullptr_t. [?Note: std?::?nullptr_t is a distinct type that is neither a pointer type nor a pointer to member type; rather, a prvalue of this type is a null pointer constant and can be converted to a null pointer value or null member pointer value. See [conv.ptr] and [conv.mem]. ?—?end note?]
Solution 3:[3]
As unintuitive as it sounds, std::nullptr_t
is not a pointer type. For instance, you cannot dereference a std::nullptr_t
, so it'd be pretty weird if is_pointer_type<nullptr_t>::value
was true
.
It is merely convertible to any pointer type.
Solution 4:[4]
Because std::nullptr_t is not a pointer type itself, but the type of the null pointer literal nullptr
.
std::nullptr_t
is the type of the null pointer literal,nullptr
. It is a distinct type that is not itself a pointer type or a pointer to member type.
From the standard, 21.2.3 Null pointers [support.types.nullptr]
The type
nullptr_t
is a synonym for the type of anullptr
expression, and it has the characteristics described in [basic.fundamental] and [conv.ptr].
Solution 5:[5]
It's definitely unintuitive in some cases, but it makes sense:
Value-wise, it doesn't behave like a pointer; it cannot point to anything.
For example, you cannot doT *p = ...; reinterpret_cast<T *>(reinterpret_cast<std::nullptr_t>(p));
and expect to get a pointer to the same address that
p
points to.Type-wise, it doesn't behave like a pointer. For example,
std::is_pointer<P>::value
should imply
std::is_same<P, std::remove_pointer<P>::type *>::value
but that clearly isn't the case.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Nicol Bolas |
Solution 2 | |
Solution 3 | zneak |
Solution 4 | |
Solution 5 | user541686 |