加倍为真/假

时间:2012-06-26 23:06:20

标签: c++ if-statement type-conversion scoping variable-declaration

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

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

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

  1. 这是宣言
  2. 这是双重的。
  3. 编辑: 它在6.3.2.1 C ++编程语言中作为推荐。

    Edit2:templatetypedefs指针的建议,特别是动态强制转换,可能会让人深入了解Bjarnes的建议。

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

4 个答案:

答案 0 :(得分: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语句。”

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

希望这有帮助!

答案 1 :(得分: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...
}

答案 2 :(得分:2)

if语句谓词赋值表达式中赋给变量的值。如果double计算为除0.0之外的任何值,它将运行内部代码。

请注意,您不应该将双打与零进行比较,但它通常可以用我的经验。

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

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

答案 3 :(得分:2)

这既是宣言也是双重。这完全等同于

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

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

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