Reputation: 47814
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?
Upvotes: 29
Views: 6265
Reputation: 1796
C++11 corrects this by introducing a new keyword to serve as a distinguished null pointer constant: nullptr. It is of type nullptr_t, which is implicitly convertible and comparable to any pointer type or pointer-to-member type. It is not implicitly convertible or comparable to integral types, except for bool. While the original proposal specified that an rvalue of type nullptr should not be convertible to bool, the core language working group decided that such a conversion would be desirable, for consistency with regular pointer types. The proposed wording changes were unanimously voted into the Working Paper in June 2008.[2]
For backwards compatibility reasons, 0 remains a valid null pointer constant.
char *pc = nullptr; // OK
int *pi = nullptr; // OK
bool b = nullptr; // OK. b is false.
int i = nullptr; // error
Upvotes: 0
Reputation: 145299
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.
}
Upvotes: 41
Reputation: 507055
In http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#654 , Jason Merril argues
Anything we can do with an arbitrary pointer, we ought to be able to do with nullptr_t as well.
I think the following (slightly artificial) example supports that argument (although I am not totally sure if it was intended for this case)
template<typename T, typename P>
void safeProcess(T pointer, P &processor) {
bool isNonNull(pointer);
if(isNonNull) {
processor.process(pointer);
}
}
Which would allow passing nullptr
along with other pointer types compatible with whatever processor.process
accepts.
Upvotes: 4
Reputation: 122403
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.
Upvotes: 18