Bjarne建议使用if中的条件作为范围限制。特别是这个例子。
if ( double d = fd() ) {
// d in scope here...
}
我很好奇如何以真/假的方式解释声明。
编辑: 它在6.3.2.1 C ++编程语言中作为推荐。
Edit2:templatetypedefs指针的建议,特别是动态强制转换,可能会让人深入了解Bjarnes的建议。
SteveJessop告诉我: - 条件不是表达式,它也可以是声明,使用的值是被评估的值。
答案 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类型具有一些问题。