I don't understand why following code compiles ?
int main() { //int a = nullptr; // Doesn't Compile //char b = nullptr; // Doesn't Compile bool c = nullptr; // Compiles return 0; }
whereas the commented section doesn't.
I've already gone through this and this.
Both bool
and nullptr
are keywords, so what's unique about the other data types?
The C++11 standard introduced a new keyword, nullptr as a null pointer constant. The nullptr constant can be distinguished from integer 0 for overloaded functions.
nullptr is a new keyword introduced in C++11. nullptr is meant as a replacement to NULL . nullptr provides a typesafe pointer value representing an empty (null) pointer. The general rule of thumb that I recommend is that you should start using nullptr whenever you would have used NULL in the past.
The C standard requires that NULL be defined in locale. h , stddef. h , stdio.
In C++11 and beyond, a pointer that is ==NULL will also ==nullptr and vice versa. Uses of NULL other than comparing with a pointer (like using it to represent the nul byte at the end of a string) won't work with nullptr .
For the same reason as
if( p ) { ... }
compiles: any value of basic type converts implicitly to boolean, with 0
converting to false
and any other value to true
.
Originally basic type values had to convert to bool
for C compatibility. C didn't originally have a bool
type, but any numerical expression could be used as a boolean (with the 0 == false
convention). And now we're caught in the backward compatibility tangle. nullptr
has to support idiomatic constructs such as if(p)
, especially for the cases where old code's literal 0
or NULL
is replaced with nullptr
. E.g. code like if(p)
can result from a macro expansion, or in template code.
Addendum: the technical how of why nullptr
doesn't convert to e.g. int
.
Since nullptr
converts implicitly to bool
, and bool
(unfortunately) converts implicitly to int
, one could expect that nullptr
should also convert to int
. But the point of nullptr
is that it should behave as a pointer value. And while pointers do convert implicitly to bool
, they do not convert implicitly to numerical types.
Arranging such a restriction for a user-defined type is however not entirely straightforward. An operator bool
conversion will be invoked for conversion to int
, if it's present. One C++11 solution to enfore the restriction, is to make the conversion operator a template, restricted by a std::enable_if
, as follows:
#include <type_traits> // std::enable_if, std::is_same struct S { template< class Type > operator Type* () const { return 0; } template< class Bool_type, class Enabled = typename std::enable_if< std::is_same<Bool_type, bool>::value, void >::type > operator Bool_type () const { return false; } }; auto main() -> int { bool const b = S(); // OK. double const* const p = S(); // OK. int const i = S(); // !Doesn't compile. }
C++11 §4.12 Boolean conversions
A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type
bool
. A zero value, null pointer value, or null member pointer value is converted tofalse
; any other value is converted totrue
. A prvalue of typestd::nullptr_t
can be converted to a prvalue of typebool
; the resulting value isfalse
.
It's true that nullptr
is a keyword, but it's a null pointer literal, not the same role as bool
. Think about the boolean literals, true
and false
are also keywords.
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