double as true / false

泪湿孤枕 提交于 2019-12-08 19:32:01

问题


Bjarne suggests using the condition in if's as scope restriction. In particular this example.

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

I'm curios how to interpret the declaration in a true / false sense.

  1. It's a declaration
  2. It's a double.

Edit: It's in 6.3.2.1 The C++ programming language as a recommendation.

Edit2: templatetypedefs suggestion of pointers, in particular with dynamic casts, might give insight to Bjarnes suggestion.

SteveJessop tells me: - A condition is not an expression it can also be a declaration, the value used, is the value being evaluated.


回答1:


The code that you're seeing is a specialized technique for declaring variables in if statements. You commonly see something like this:

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. */
}

A particularly common case is the use of dynamic_cast here:

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. */
}

What's happening in your case is that you're declaring a double inside the if statement. C++ automatically interprets any nonzero value as true and any zero value as false. What this code means is "declare d and set it equal to fd(). If it is nonzero, then execute the if statement."

That said, this is a Very Bad Idea because doubles are subject to all sorts of rounding errors that prevent them from being 0 in most cases. This code will almost certainly execute the body of the if statement unless function is very well-behaved.

Hope this helps!




回答2:


In the example Stroustrup gives, the code in the if block divides a value by d:

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

Division by 0 is undefined behavior, so it makes some sense in this case to test d against the value 0.0 before dividing. Putting the definition in the condition is a convenient way to do this, for the reasons Stroustrup states.

Your code gives no reason why the value 0.0 would be special, and therefore it is not clear why anyone would combine the definition of d with that test. Only use Stroustrup's pattern when "false" values of the type you're defining need to be treated specially. Otherwise just do this:

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



回答3:


It is both a declaration and a double. This is quite equivalent to

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

However, this pattern is worth the small additional syntax to simplify, as it is fairly useful and common. In addition, the transformation is less obvious once you start adding else clauses, as d is out of scope for them.

Also, as others have noted, it's useful in general but FP types in specific have some issues when compared against 0.




回答4:


the if statement predicates on the value that is assigned to the variable in the assignment expression. If the double evaluates to anything but 0.0 it will run the code inside.

Note that you are not supposed to compare doubles with zero, but it generally works in my experience.

Basically, you shouldn't do this.

The other contributors to this topic have found that this expression is used to exclude the zero case so as to avoid a divide-by-zero. That's definitely smart and such a situation legitimizes this usage as far as I'm concerned (but do consider the confusion such code may cause).



来源:https://stackoverflow.com/questions/11217179/double-as-true-false

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!