nullptr 是假的吗?
Is nullptr falsy?
当用作布尔表达式或显式或隐式转换为布尔值时,nullptr
是否始终为假?此实现是否在标准中定义或指定?
我写了一些代码来测试,但不确定它是否完全测试了 属性。我找不到专门讨论这个问题的现有 SO 答案。 cppreference据我所知没有提到这个。
if (nullptr) {
;
} else {
std::cout << "Evaluates to false implicitly\n";
}
if (!nullptr) {
std::cout << "Evaluates to false if operated on\n";
}
if (!(bool)(nullptr)) {
std::cout << "Evaluates to false if explicitly cast to bool\n";
}
预期和实际:
Evaluates to false implicitly
Evaluates to false if operated on
Evaluates to false if explicitly cast to bool
你的代码的结果是有保证的,[dcl.init]/17.8
Otherwise, if the initialization is direct-initialization, the source type is std::nullptr_t
, and the destination type is bool
, the initial value of the object being initialized is false
.
这意味着,对于直接初始化,bool
对象可以从 nullptr
初始化,结果值为 false
。然后对于 (bool)(nullptr)
,nullptr
转换为 bool
,值为 false
。
当nullptr
作为if
的条件或operator!
的操作数时,被认为是contextual conversions,
the implicit conversion is performed if the declaration bool t(e);
is well-formed
也就是说,if (nullptr)
和!nullptr
,nullptr
都会被转换成bool
,值为false
。
根据 C++ 17 标准(5.13.7 指针文字)
1 The pointer literal is the keyword nullptr. It is a prvalue of type
std::nullptr_t. [ Note: std::nullptr_t is a distinct type that is
neither a pointer type nor a pointer-to-member type; rather, a prvalue
of this type is a null pointer constant and can be converted to a
null pointer value or null member pointer value. See 7.11 and 7.12. —
end note ]
和(7 个标准转换)
4 Certain language constructs require that an expression be converted
to a Boolean value. An expression e appearing in such a context is
said to be contextually converted to bool and is well-formed if and
only if the declaration bool t(e); is well-formed, for some invented
temporary variable t (11.6).
最后(7.14 布尔转换)
1 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 to false; any other value is converted to true. For
direct-initialization (11.6), a prvalue of type std::nullptr_t can be
converted to a prvalue of type bool; the resulting value is false.
也就是你可以这样写
bool b( nullptr );
但你可能不会写(尽管一些编译器有一个与此相关的错误)
bool b = nullptr;
因此 nullptr
可以根据上下文转换为 bool 类型的对象,例如在 if 语句等选择语句中。
让我们考虑例如 if 语句中的一元运算符 !
if ( !nullptr ) { /*...*/ }
根据运算符的描述(8.5.2.1 一元运算符)
9 The operand of the logical negation operator ! is contextually
converted to bool (Clause 7); its value is true if the converted
operand is false and false otherwise. The type of the result is bool
所以这个表达式中的nullptr
没有转换为指针。它直接根据上下文转换为 bool.
是的,但你应该避免使用这个事实。
比较指向 false
或 0
的指针是 C/C++ 编码中的常见比喻。我建议您避免使用它。如果要检查是否为空,请使用:
if (x == nullptr) { /* ... */}
而不是
if (!x) { /* ... */}
或
if (not x) { /* ... */}
第二个变体为reader增加了一点混乱:什么是x
?它是布尔值吗?普通值(例如整数)?指针?一个可选的?即使 x
有一个有意义的名字,它也不会对你有多大帮助: if (!network_connection)
...它仍然可以是一个复杂的结构,可以转换为一个整数或一个布尔值,它可能是一个布尔指示符无论是否存在连接,它都可以是一个指针、一个值或一个可选的。或者别的。
此外,记住 nullptr
的计算结果为 false 是您需要存储在大脑后部的另一位信息,以正确解码您正在阅读的代码。我们可能从过去或阅读其他人的代码时就习惯了它 - 但如果我们不习惯,那么 nullptr
的行为就不会很明显。从某种意义上说,它与其他晦涩的保证并没有什么不同,比如。除非绝对必要,否则不要让你的代码依赖这些东西。
PS : 现在空指针的使用实际上少了很多。如果他们不需要,你可以 force pointers to never be null;您可以使用引用而不是指针;您可以使用 std::optional<T>
到 return T
或“无 T”。也许你可以完全避免提及 nullptr
。
当用作布尔表达式或显式或隐式转换为布尔值时,nullptr
是否始终为假?此实现是否在标准中定义或指定?
我写了一些代码来测试,但不确定它是否完全测试了 属性。我找不到专门讨论这个问题的现有 SO 答案。 cppreference据我所知没有提到这个。
if (nullptr) {
;
} else {
std::cout << "Evaluates to false implicitly\n";
}
if (!nullptr) {
std::cout << "Evaluates to false if operated on\n";
}
if (!(bool)(nullptr)) {
std::cout << "Evaluates to false if explicitly cast to bool\n";
}
预期和实际:
Evaluates to false implicitly
Evaluates to false if operated on
Evaluates to false if explicitly cast to bool
你的代码的结果是有保证的,[dcl.init]/17.8
Otherwise, if the initialization is direct-initialization, the source type is
std::nullptr_t
, and the destination type isbool
, the initial value of the object being initialized isfalse
.
这意味着,对于直接初始化,bool
对象可以从 nullptr
初始化,结果值为 false
。然后对于 (bool)(nullptr)
,nullptr
转换为 bool
,值为 false
。
当nullptr
作为if
的条件或operator!
的操作数时,被认为是contextual conversions,
the implicit conversion is performed if the declaration
bool t(e);
is well-formed
也就是说,if (nullptr)
和!nullptr
,nullptr
都会被转换成bool
,值为false
。
根据 C++ 17 标准(5.13.7 指针文字)
1 The pointer literal is the keyword nullptr. It is a prvalue of type std::nullptr_t. [ Note: std::nullptr_t is a distinct type that is neither a pointer type nor a pointer-to-member type; rather, a prvalue of this type is a null pointer constant and can be converted to a null pointer value or null member pointer value. See 7.11 and 7.12. — end note ]
和(7 个标准转换)
4 Certain language constructs require that an expression be converted to a Boolean value. An expression e appearing in such a context is said to be contextually converted to bool and is well-formed if and only if the declaration bool t(e); is well-formed, for some invented temporary variable t (11.6).
最后(7.14 布尔转换)
1 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 to false; any other value is converted to true. For direct-initialization (11.6), a prvalue of type std::nullptr_t can be converted to a prvalue of type bool; the resulting value is false.
也就是你可以这样写
bool b( nullptr );
但你可能不会写(尽管一些编译器有一个与此相关的错误)
bool b = nullptr;
因此 nullptr
可以根据上下文转换为 bool 类型的对象,例如在 if 语句等选择语句中。
让我们考虑例如 if 语句中的一元运算符 !
if ( !nullptr ) { /*...*/ }
根据运算符的描述(8.5.2.1 一元运算符)
9 The operand of the logical negation operator ! is contextually converted to bool (Clause 7); its value is true if the converted operand is false and false otherwise. The type of the result is bool
所以这个表达式中的nullptr
没有转换为指针。它直接根据上下文转换为 bool.
是的,但你应该避免使用这个事实。
比较指向 false
或 0
的指针是 C/C++ 编码中的常见比喻。我建议您避免使用它。如果要检查是否为空,请使用:
if (x == nullptr) { /* ... */}
而不是
if (!x) { /* ... */}
或
if (not x) { /* ... */}
第二个变体为reader增加了一点混乱:什么是x
?它是布尔值吗?普通值(例如整数)?指针?一个可选的?即使 x
有一个有意义的名字,它也不会对你有多大帮助: if (!network_connection)
...它仍然可以是一个复杂的结构,可以转换为一个整数或一个布尔值,它可能是一个布尔指示符无论是否存在连接,它都可以是一个指针、一个值或一个可选的。或者别的。
此外,记住 nullptr
的计算结果为 false 是您需要存储在大脑后部的另一位信息,以正确解码您正在阅读的代码。我们可能从过去或阅读其他人的代码时就习惯了它 - 但如果我们不习惯,那么 nullptr
的行为就不会很明显。从某种意义上说,它与其他晦涩的保证并没有什么不同,比如
PS : 现在空指针的使用实际上少了很多。如果他们不需要,你可以 force pointers to never be null;您可以使用引用而不是指针;您可以使用 std::optional<T>
到 return T
或“无 T”。也许你可以完全避免提及 nullptr
。