In C++98, the null pointer was represented by the literal 0
(or in fact any constant expression whose value was zero). In C++11, we prefer nullptr
The C++11 grammar only allows 0
here (and it doesn't mean a pointer). As nullptr
is not 0
, it fails. NULL
only works when NULL
is defined to be 0
(sometimes it's the case, but not always). Just use 0
here, or use following define (if you really want to use a null, when it's not a pointer).
#define VIRTUAL_NULL 0
struct X
{
virtual void foo() = VIRTUAL_NULL;
};
This is just how the grammar is defined, if we look at the draft C++ standard section 9.2
Class members the relevant grammar is as follows:
[...]
member-declarator:
declarator virt-specifier-seqopt pure-specifieropt
[...]
pure-specifier:
= 0
^^^
The grammar specifically indicates that a pure-specifier is = 0
and not an integer literal or expression, that does not seem to leave any wiggle room. If I attempt things like:
virtual void foo() = 0L;
or:
virtual void foo() = NULL ;
gcc
tells me:
error: invalid pure specifier (only '= 0' is allowed) before ';' token
and clang
says:
error: initializer on function does not look like a pure-specifier
Although the following does work in both:
#define bar 0
//...
virtual void foo() = bar;
It also seems like clang
allows octal literal, hexadecmical literal and binary literal zero which is incorrect behavior.
Update
Apparently Visual Studio
accepts NULL
and any zero integer literal including 0L
, 0x0
, 00
etc... Although it does not accept nullptr
.
That doesn't mean it is a pointer, or that it has to be equal to nullptr
.
= 0
is sufficient and means that the virtual function is to be pure.
The = 0
notation for virtual
functions wasn't literally "assign null" but rather a special notation which is actually deceptive: a pure virtual function can also be implemented.
With various context keywords it would make more sense to allow abstract
rather than = nullptr
and have abstract
be a context keyword.
The whole point of nullptr
(or most of the point anyway) is that can only be assigned to (or used to initialize) pointers.
In this case, you're not initializing or assigning to a pointer, so it doesn't even make sense that you would be able to use it in this situation.
= 0
has a fixed meaning there. It's not really an integer zero there. Therefore, you can't simply replace it like that.