29

我不明白为什么下面的代码会编译

int main()
{
     //int a = nullptr;  // Doesn't Compile
     //char b = nullptr; // Doesn't Compile
       bool c = nullptr; // Compiles

       return 0;
}

而评论部分没有。


我已经经历过这个这个

bool和都是nullptr关键字,那么其他数据类型有什么独特之处呢?

4

4 回答 4

42

出于同样的原因

if( p ) { ... }

编译:任何基本类型的值都隐式转换为布尔值,并0转换为false和任何其他值true

最初基本类型值必须转换bool为 C 兼容性。C 最初没有bool类型,但任何数值表达式都可以用作布尔值(使用 0 ==false约定)。现在我们陷入了向后兼容性的纠结中。nullptr必须支持惯用构造,例如if(p),尤其是在旧代码的文字0或被NULL替换为nullptr. 例如,类似代码if(p)可能来自宏扩展或模板代码。


附录:为什么不转换为例如的技术方法nullptrint

由于nullptr隐式转换为bool,并且bool(不幸地)隐式转换为int,因此可以预期它nullptr也应该转换为int。但关键nullptr是它应该表现为一个指针值。虽然指针确实隐式转换为bool,但它们不会隐式转换为数值类型。

然而,为用户定义的类型安排这样的限制并不完全简单。如果存在,operator bool将调用转换以转换为int。一个 C++11 的解决方案是使转换运算符成为模板,受 a 限制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.
}
于 2014-02-25T11:32:03.743 回答
19

C++11 §4.12布尔转换

算术、无作用域枚举、指针或指向成员类型的指针的纯右值可以转换为类型的纯右值bool。零值、空指针值或空成员指针值转换为false; 任何其他值都转换为true. 类型的纯右值std::nullptr_t可以转换为类型的纯右值bool;结果值为false

确实nullptr是关键字,但它是一个空指针字面量,与bool. 想想布尔文字,true也是false关键字。

于 2014-02-25T11:36:52.740 回答
5

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#654中,Jason Merril 认为

我们可以用任意指针做的任何事情,我们也应该可以用 nullptr_t 做。

我认为以下(稍微人为的)示例支持该论点(尽管我不完全确定它是否适用于这种情况)

template<typename T, typename P>
void safeProcess(T pointer, P &processor) {
  bool isNonNull(pointer);
  if(isNonNull) {
    processor.process(pointer);
  }
}

这将允许与其他与任何接受nullptr兼容的指针类型一起传递。processor.process

于 2014-02-25T13:11:10.297 回答
0

C++11 通过引入一个新的关键字来作为一个可区分的空指针常量来纠正这个问题:nullptr。它是 nullptr_t 类型,可隐式转换并与任何指针类型或指向成员的指针类型相当。除了 bool 之外,它不能隐式转换或与整数类型相比较。虽然最初的提案规定 nullptr 类型的右值不应转换为 bool,但核心语言工作组认为这种转换是可取的,以与常规指针类型保持一致。拟议的措辞更改于 2008 年 6 月被一致投票纳入工作文件。 [2]

出于向后兼容的原因,0 仍然是一个有效的空指针常量。

char *pc = nullptr;     // OK
int  *pi = nullptr;     // OK
bool   b = nullptr;     // OK. b is false.
int    i = nullptr;     // error
于 2014-10-11T18:40:26.717 回答