6

Bjarne 建议使用 if 中的条件作为范围限制。特别是这个例子。

if ( double d = fd()  ) {
   // d in scope here...
}

我很好奇如何以真/假的方式解释声明。

  1. 这是一个宣言
  2. 是双倍的。

编辑:它在 6.3.2.1 C++ 编程语言中作为推荐。

Edit2:templatetypedefs 对指针的建议,特别是动态转换,可能会给 Bjarnes 建议提供洞察力。

SteveJessop 告诉我: - 条件不是表达式,它也可以是声明,使用的值是正在评估的值。

4

4 回答 4

6

您看到的代码是一种在if语句中声明变量的专用技术。你通常会看到这样的东西:

if (T* ptr = function()) {
    /* ptr is non-NULL, do something with it here */
} else {
    /* ptr is NULL, and moreover is out of scope and can't be used here. */
}

一个特别常见的情况是使用dynamic_cast这里:

if (Derived* dPtr = dynamic_cast<Derived*>(basePtr)) {
     /* basePtr really points at a Derived, so use dPtr as a pointer to it. */
} else {
     /* basePtr doesn't point at a Derived, but we can't use dPtr here anyway. */
}

在您的情况下发生的事情是您在声明中声明了double一个if。C++ 自动将任何非零值解释为true,将任何零值解释为false. 这段代码的意思是“声明d并设置它等于fd()。如果它不为零,则执行该if语句。”

也就是说,这是一个非常糟糕的主意,因为doubles 会受到各种舍入错误的影响,这些错误会在大多数情况下阻止它们为 0。除非表现得非常好,否则这段代码几乎肯定会执行if语句的主体。function

希望这可以帮助!

于 2012-06-26T23:11:07.660 回答
5

在 Stroustrup 给出的示例中,if块中的代码将一个值除以d

if (double d = prim(true)) {
    left /= d;
    break;
}

除以 0 是未定义的行为,因此在这种情况下,在除以之前测试d该值是有意义的。0.0出于 Stroustrup 所述的原因,将定义置于条件中是一种方便的方法。

您的代码没有说明为什么该值0.0会特别,因此不清楚为什么有人会将定义d与该测试结合起来。仅当您定义的类型的“假”值需要特殊处理时,才使用 Stroustrup 模式。否则就这样做:

{
    double d = fd();
    // d in scope here...
}
于 2012-06-26T23:33:47.653 回答
2

if语句基于赋值表达式中分配给变量的值。如果 double 计算结果为 0.0 以外的任何值,它将在内部运行代码。

请注意,您不应该将双打与零进行比较,但根据我的经验,它通常有效。

基本上,你不应该这样做。

该主题的其他贡献者发现此表达式用于排除零情况,以避免被零除。这绝对是聪明的,就我而言,这种情况使这种用法合法化(但请考虑这种代码可能导致的混乱)。

于 2012-06-26T23:08:44.957 回答
2

它既是声明也是双重的。这完全等同于

{
    double d = fd();
    if (d) {
    }
}

但是,这种模式值得用一些额外的小语法来简化,因为它非常有用且很常见。此外,一旦您开始添加 else 子句,转换就不那么明显了,因为d超出了它们的范围。

此外,正如其他人所指出的,它通常很有用,但与 0 相比,特定的 FP 类型存在一些问题。

于 2012-06-26T23:11:16.547 回答