【问题标题】:Why can't nullptr convert to int?为什么 nullptr 不能转换为 int?
【发布时间】:2012-10-17 00:49:24
【问题描述】:

总结:nullptr 转换为boolbool 转换为int,那么为什么nullptr 不转换为int

这段代码没问题:

void f(bool);
f(nullptr);      // fine, nullptr converts to bool

这没关系:

bool b;
int i(b);        // fine, bool converts to int

那为什么不行呢?

void f(int);
f(nullptr);      // why not convert nullptr to bool, then bool to int?

【问题讨论】:

  • 您希望转换是什么?
  • 编译器只会从你传递的内容到函数接受的内容进行一次隐式转换。这基本上适用于所有类型,而不仅仅是 nullptr 的。例如,如果您定义一个转换为char 的类型并尝试将其传递给一个接受int 的函数,即使它支持隐式转换为char,它也会失败,并且还有一个从charint 的隐式转换。
  • @JerryCoffin 编译器通常会进行不止一次的隐式转换。它只会进行一次用户定义的转换,但它可以根据规则进行任意数量的其他转换。有一条规则,在任何给定的类别中最多可以应用一次转换,nullptr_tboolbool 到各种整数类型都属于“转换”类别(参见 13.2.2.1.1)。
  • 我认识伯特,伯特认识汉斯,汉斯认识奥巴马。所以我认识奥巴马!

标签: c++ c++11 implicit-conversion nullptr


【解决方案1】:

因为这正是nullptr的主要思想。

nullptr 是为了避免这种行为:

struct myclass {};

void f(myclass* a) { std::cout << "myclass\n"; }
void f(int a) { std::cout << "int\n"; }

// ...

f(NULL); // calls void f(int)

如果 nullptr 可转换为 int,则会发生此行为。

所以问题是“为什么它可以转换为 bool?”。

语法-“糖”:

int* a = nullptr;
if (a) {
}

这看起来比:

if (a == nullptr) {
}

【讨论】:

  • @David:不,是的。 nullptr 背后的原因是它转换为指针类型以外的任何东西。
  • @Xeo 我认为“为什么 不能 它”这个问题不同于“为什么 它”或“为什么不应该”。在这种情况下,这个答案并不是真正的答案。
  • @Xeo 阅读答案,看看您是否可以在其中找到该信息。
  • @SethCarnegie:“为什么不能”这个问题很容易用“因为规范这么说”来回答。由于这在任何实际意义上都简单、明显且完全无用,因此问题显然是隐含地询问禁止转换背后的原因
  • @MuriloVasconcelos 在您的示例中,if (a)int* 转换为bool,而不是将nullptr 转换为bool
【解决方案2】:

在标准的 §4.1 中,它说明了如何执行转换:

标准转换是具有内置含义的隐式转换。第 4 条列举了所有此类转换。标准转换序列是按以下顺序进行的标准转换序列:

- 从以下集合进行零次或一次转换:左值到右值的转换、数组到指针的转换和函数到指针的转换。

- 来自以下集合的零个或一个转换:整数提升、浮点提升、整数转换、浮点转换、浮点整数转换、指针转换、指向成员的指针转换和布尔转换。

— 零个或一个资格转换。

因此编译器仅对上述每种类型的转换中的一些、无或全部进行“零或一次转换”,而不是任意多次。这是一件非常好的事情

【讨论】:

  • +1:回答,赛斯。我很难说,但这里列出的转化类别(三个特定类别)是否也相互排斥彼此?标准对我来说只是有点灰色(或者我没有正确阅读,这不是第一次)。
  • @WhozCraig 不,它们都是按顺序完成的,没有,一个,两个,或者三个全部;是包容的。使用 aschepler 的示例:void f(const int*); int my_array[10]; f(my_array); 将数组转换为指针,然后将指针转换为 const 指针。
  • 好的,那么它们至少看起来像瀑布,标准确实说明了这一点(即一旦一个 conv 被填满,就不会返回列表;你只能往下走。我认为..)
  • @WhozCraig 是的。如果它可以从前面的步骤重新开始,那就意味着其中一个可以多次完成,这与它所说的相反。
【解决方案3】:

要了解为什么会发生这种情况,您应该了解如何使用nullptr。检查以下链接:

希望对你有帮助。

【讨论】:

    【解决方案4】:

    keyworkd nullptr是在c++11中引入的,因为C中NULL的定义是多重的,当用int参数和NULL重载函数时会造成混淆。 p>

    #define NULL 0
    #define NULL (void*)0
    

    圣经中的 C++ 编程语言(第 4 期),第 270 页

    指针到布尔值的转换在条件下很有用,但在其他地方会令人困惑。

    所以我认为 nullptr_t 变量转换为 int 是不允许的,因为这就是它存在的原因,但它可以像 bool 变量一样用作测试条件。

    【讨论】:

      猜你喜欢
      • 2012-07-02
      • 1970-01-01
      • 2013-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-18
      • 1970-01-01
      • 2018-10-26
      相关资源
      最近更新 更多