We now have C++11 with many new features. An interesting and confusing one (at least for me) is the new nullptr
.
Well, no need anymore for the nasty mac
When you have a function that can receive pointers to more than one type, calling it with NULL
is ambiguous. The way this is worked around now is very hacky by accepting an int and assuming it's NULL
.
template <class T>
class ptr {
T* p_;
public:
ptr(T* p) : p_(p) {}
template <class U>
ptr(U* u) : p_(dynamic_cast<T*>(u)) { }
// Without this ptr<T> p(NULL) would be ambiguous
ptr(int null) : p_(NULL) { assert(null == NULL); }
};
In C++11
you would be able to overload on nullptr_t
so that ptr<T> p(42);
would be a compile-time error rather than a run-time assert
.
ptr(std::nullptr_t) : p_(nullptr) { }
According to cppreference, nullptr
is a keyword that:
denotes the pointer literal. It is a prvalue of type
std::nullptr_t
. There exist implicit conversions from nullptr to null pointer value of any pointer type and any pointer to member type. Similar conversions exist for any null pointer constant, which includes values of typestd::nullptr_t
as well as the macroNULL
.
nullptr
will convert implicitly to any pointer type but not to an integer. NULL
, however, is a macro and it is an implementation-defined null pointer constant. It's often defined like this:
#define NULL 0
i.e. an integer.
Hence:
int i = NULL; //OK
int i = nullptr; //error
int* p = NULL; //OK
int* p = nullptr; //OK
nullptr
can avoid ambiguity when you have two function overloads like this:
void func(int x); //1)
void func(int* x); //2)
func(NULL)
calls 1) because NULL
is an integer.
func(nullptr)
calls 2) because nullptr
is not an integer and converts implicitly to any pointer type.
Advantages of using nulptr:
if (ptr == nullptr)
instead of if (ptr == 0)