根据标准N4713(7.11 / 1)的草案:
空指针常量是一个整数文字(5.13.2),其值为零或prvalue类型为
std::nullptr_t
。
和21.2.3 / 2:
宏
NULL
是一个实现定义的空指针常量。
关注NULL
可以定义为nullptr
。 cppreference上提到了相同的内容:
#define NULL 0
//since C++11
#define NULL nullptr
同时“Additive operators”子句说(8.5.6 / 7):
如果将值
0
添加到空指针值或从空指针值中减去,则结果为空指针值。如果两个为null 减去指针值,结果比较等于转换为0
类型的值std::ptrdiff_t
。
因此以下代码应该有效:
0 + nullptr;
nullptr - nullptr;
但由于std::nullptr_t
code is invalid缺少+/-运算符。
是否存在我未考虑的内容或NULL
宏无法实际定义为nullptr
?
答案 0 :(得分:47)
虽然nullptr
是空指针常量,但它不是空指针值。后者是某种指针类型的值,std::nullptr_t
不是。
参考:
空指针常量是整数文字(5.13.2),其值为零或prvalue类型为
std::nullptr_t
。 空指针常量可以转换为指针类型;结果是该类型的空指针值并且是 可与对象指针或函数指针类型的每个其他值区分开来。这种转换被称为 空指针转换。 [...]
7.11 / 1在N4659中,强调我的
所以NULL
确实可以nullptr
而不提供算术运算符。
答案 1 :(得分:7)
nullptr
是一个空指针文字,虽然将nullptr
转换为指针类型的结果是空指针值,但nullptr
本身并不是指针类型,但类型为std::nullptr_t
。如果您将nullptr
转换为指针类型,则算法有效:
0 + (int*)nullptr;
(int*)nullptr - (int*)nullptr;
NULL宏实际上可以是nullptr吗?
是的,因为nullptr
是一个空指针文字。
请注意,在C ++ 11之前,C ++中的所有空指针文字也恰好是整数文字,所以这个错误的代码:char c = NULL;
曾经在实践中工作。如果NULL
定义为nullptr
,则该代码不再有效。
答案 2 :(得分:6)
另外,两个操作数都应具有算术或非范围的枚举类型,或者一个操作数应是指向完全定义的对象类型的指针,另一个操作数应具有整数或无范围的枚举类型。
对于减法,以下之一应保持:
(2.1)两个操作数都有算术或无范围的枚举类型;或
(2.2)两个操作数都是指向同一个完全定义的对象类型的cv-qualified或cv-nonqualified版本的指针;或
(2.3)左操作数是指向完全定义的对象类型的指针,右操作数具有整数或未操作的枚举类型。
std::nullptr_t
不属于这些,因此std::nullptr
不能参与加法运算。
请注意,即使所有指针值都不能参与。例如,函数指针值和void指针值不能,即使其中任何一个都可以是空指针值。
答案 3 :(得分:5)
关键字nullptr
表示指针文字。它是prvalue
类型的std::nullptr_t
。存在从nullptr
到任何指针类型的空指针值以及指向成员类型的任何指针的隐式转换。
nullptr
本身不是指针值也不是指针。因此算术运算不适用于nullptr
。