C++ 双重为真/假

C++ 双重为真/假,c++,if-statement,type-conversion,scoping,variable-declaration,C++,If Statement,Type Conversion,Scoping,Variable Declaration,Bjarne建议使用if中的条件作为范围限制。特别是这个例子 if ( double d = fd() ) { // d in scope here... } 我对如何从真/假的意义上解释这份声明很好奇 这是一份声明 是双人房 编辑: 它是在3.3.2.1中作为C++编程语言的一种推荐。 Edit2:templatetypedefs对指针的建议,特别是对动态强制转换的建议,可能会给Bjarnes的建议带来启示 SteveJessop告诉我:-条件不是表达式,它也可以是声明,使用的值是正

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

if ( double d = fd()  ) {
   // d in scope here...
}
我对如何从真/假的意义上解释这份声明很好奇

  • 这是一份声明
  • 是双人房
  • 编辑: 它是在3.3.2.1中作为C++编程语言的一种推荐。 Edit2:templatetypedefs对指针的建议,特别是对动态强制转换的建议,可能会给Bjarnes的建议带来启示


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

    if语句以赋值表达式中赋值给变量的值为谓词。如果double的计算结果不是0.0,它将在内部运行代码

    请注意,您不应该将double与zero进行比较,但根据我的经验,它通常是有效的

    基本上,你不应该这样做


    本主题的其他参与者发现,此表达式用于排除零的情况,以避免被零除。这绝对是聪明的,这种情况在我看来是合法的(但请考虑这种代码可能造成的混乱)。

    您所看到的代码是一种专门用于在<代码>中声明变量的技术,如果语句。您通常会看到这样的情况:

    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\u 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. */
    }
    
    if(派生*dPtr=dynamic_cast(basePtr)){
    /*basePtr实际上指向一个派生对象,所以使用dPtr作为指向它的指针*/
    }否则{
    /*basePtr不指向派生的,但无论如何我们不能在这里使用dPtr*/
    }
    
    您的情况是,您在
    if
    语句中声明了一个
    double
    。C++自动解释任何非零值为<代码>真< /COD>和任何零值为<代码> false <代码>。此代码的意思是“声明
    d
    并将其设置为等于
    fd()
    。如果它不为零,则执行
    If
    语句。”

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


    希望这有帮助

    它既是一种声明,也是一种双重声明。这相当于

    {
        double d = fd();
        if (d) {
        }
    }
    
    然而,这个模式值得简化一些额外的语法,因为它非常有用和常见。此外,一旦开始添加else子句,转换就不那么明显了,因为
    d
    超出了它们的范围


    另外,正如其他人所指出的,它在一般情况下是有用的,但与0相比,特定的FP类型有一些问题。

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

    if (double d = prim(true)) {
        left /= d;
        break;
    }
    
    被0除法是未定义的行为,因此在这种情况下,在除法之前根据值
    0.0
    测试
    d
    是有意义的。将定义放在条件中是一种方便的方法,原因如下

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

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

    对的回答也将回答您的问题。我刚刚阅读了您正在谈论的部分,并感觉到讨论更多的是将其用作范围限制(并获得紧凑代码的额外好处),与特定的数据类型没有太多关系。我认为他本可以用
    int
    替换
    double
    ,并且仍然能够传达他想要传达的信息。“我就是这么读的。”杰德瓦兹说,“是的,但是使用double这个词需要一个答案。int声明仍然是一个异常,值得回答。@Giraffe船长:声明不是一个表达式。
    if
    语句的语法是“if(condition)statement”,而condition的语法是“expression”或“type specifier seq declarator=assignment expression”
    double d=fd()
    是后者。请参阅<代码> [STM.SELECT] <代码> >标准。@不幸的是,编写代码的人,比如C++,而你没有,所以我认为你的偏好不会赢。这就是说,Stroustrup用斜体而不是像其他人一样固定宽度来放置代码片段。比亚恩告诉我这是一个成语。只是说说而已。3.3.2.1 C++编程语言。他可能指的是双代码> d>代码>在“代码”>(< /代码>块)的内部(并且仅在内部)。这不一定是显而易见的。我的观点是,通常没有很好的理由投双杀。我不知道为什么不使用
    int
    类型的变量。(这是一个非常常见的习语)你到底为什么不把双倍和零进行比较?它工作得非常好,并且具有明确的行为。浮点数学可能令人惊讶,但它不是巫毒教,也不是那种建议的好方法。这不是一个好习惯(比较浮点值)。零可能是一种特殊情况,因为对于浮点类型的所有实现,0位等效于等效大小整数类型的0。但是,当您得到类似于给定示例的内容时,不清楚
    fd()
    返回的值是非常接近零(但实际上不是零)还是零。如果这项技术实际用于排除零的情况(因此不会出现被零除的情况),那么这是一件好事!切勿使用整数比较来测试浮点零。0x8000000是32位(负)零。我的p