出于同样的原因
if( p ) { ... }
0
转换为false
,其他任何值转换为true
。bool
以实现C兼容性。C最初没有bool
类型,但是任何数值表达式都可以用作布尔值(使用0 == false
约定)。现在我们陷入了向后兼容的混乱中。nullptr
必须支持惯用结构,例如if(p)
,特别是对于将旧代码的文字0
或NULL
替换为nullptr
的情况。例如,宏扩展或模板代码可能导致类似于if(p)
的代码。nullptr
不会转换为int
的技术细节。nullptr
隐式转换为bool
,而bool
(不幸地)隐式转换为int
,因此可以期望nullptr
也应该转换为int
。但是nullptr
的重点在于它应该像一个指针值一样行为。而指针虽然隐式转换为bool
,但不会隐式转换为数值类型。operator bool
转换,则将调用该转换以进行向int
的转换。一个C++11解决方案是使转换运算符成为模板,并受到std::enable_if
的限制,如下所示:#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.
}
p
不是一个空指针常量。你为什么要写字面上的 if(nullptr) { ... }
? - Johannes Schaub - litbnullptr
和 nullptr_t
是C++中独有的,所以我不太明白这里的原因(这就是我撰写第一条评论的原因)。 - Johannes Schaub - litbnullptr_t
不需要转换为 bool
。这可能有点奇怪,因为 if (nullptr)
会编译失败,而 if( ptr = nullptr )
则会编译通过,但是... 然而,如果你编写了一个 template
函数,其中一个参数类似于指针,那么能够传递 nullptr
就很好了,然后 if
子句就会发生。 - Yakk - Adam Nevraumontif( ptr = nullptr )
会得到一个警告。 - Vladimir F Героям слава算术、未作用域枚举、指针或成员指针类型的 prvalue 可以转换为类型为 bool
的 prvalue。零值、空指针值或空成员指针值转换为false
;其他任何值转换为true
。类型为 std::nullptr_t
的 prvalue 可以转换为类型为 bool
的 prvalue;转换后的值为false
。
虽然nullptr
是关键字,但它是空指针文字(null pointer literal),不同于bool
的角色。想一下布尔文字,true
和false
也是关键字。
nullptr
可以转换为bool
。<2>为什么它在语法上可以用于=
的右侧,而显然你不能在那里放置bool
(也是一个关键字)。因为nullptr
是一个字面量,就像42
或true
(另一个关键字是字面量)。也许我们对OP主要提出的问题有不同的看法,但我认为我的回答至少回答了OP的一些问题。 - Yu Haonullptr
与bool
不是同一种关键字类型,它的角色是指针类型的字面量,就像bool
类型的true
一样,但正如我刚才看到的OP的评论,这不是他主要问的。如果我能想到与@Alf和您的答案不同的观点,我肯定会更新我的答案以更好地适应OP澄清的问题。 - Yu Hao我们可以使用任意指针执行的操作,同样也应该能够使用nullptr_t执行。
我认为以下(稍微人为制造的)示例支持这个观点(尽管我不确定它是否是为这种情况而设计的)。
template<typename T, typename P>
void safeProcess(T pointer, P &processor) {
bool isNonNull(pointer);
if(isNonNull) {
processor.process(pointer);
}
}
这将允许传递nullptr
以及与processor.process
兼容的其他指针类型。
C++11通过引入一个新的关键字nullptr来纠正这个问题,作为一个特殊的空指针常量。它是nullptr_t类型的,可以隐式转换和比较任何指针类型或指向成员的指针类型。它不能隐式转换或与整数类型比较,除了bool类型。虽然最初的提案规定nullptr类型的右值不应该转换为bool类型,但核心语言工作组决定这样的转换是可取的,以保持与常规指针类型的一致性。这些提议的措辞变更在2008年6月的工作文件中被一致投票通过。
出于向后兼容性的原因,0仍然是一个有效的空指针常量。
char *pc = nullptr; // OK
int *pi = nullptr; // OK
bool b = nullptr; // OK. b is false.
int i = nullptr; // error
nullptr
不能转换为基本数据类型,例如char
、int
? - P0W