也许我变得生疏了(最近用Python编写)。
为什么不编译?
if ( (int i=f()) == 0)
在()
周围没有int i=f()
我得到另一个,i
更合理的错误不是布尔值。但这就是我首先想要括号的原因!
我的猜测是使用括号使其成为表达式,并且表达式中不允许使用声明语句。是这样吗?如果是的话,它是C ++的语法怪癖之一吗?
顺便说一下,我其实是在尝试这样做:if ( (Mymap::iterator it = m.find(name)) != m.end())
return it->second;
答案 0 :(得分:38)
您可以在C ++中的if
语句中声明一个变量,但它只能用于直接初始化,需要转换为布尔值:
if (int i = f()) { ... }
C ++没有任何可以被描述为“声明表达式”的东西,即声明变量的[sub-]表达式。
实际上,我只是查阅了标准中的条款,并且根据6.4 [stmt.select]第1段支持两种形式的初始化:
...
condition:
expression
attribute-specifier-seqopt decl-specifier-seq declarator = initializer-clause
attribute-specifier-seqopt decl-specifier-seq declarator braced-init-list
...
也就是说,也可以写:
if (int i{f()}) { ... }
显然,这仅适用于C ++ 2011,因为C ++ 2003没有大括号初始化。
答案 1 :(得分:20)
范围有问题。
请考虑以下代码:
if ((int a = foo1()) || (int b = foo2()))
{
bar(b);
}
是否在块内声明了?如果foo1()
返回true,该怎么办?
答案 2 :(得分:5)
你可以在if语句中声明一个变量(或者在for或while中),但只能在外括号中声明,并且它需要能够转换为bool。
你的猜测基本上是对的,不允许这样做,因为
(int i = 42;)
不是初始化的有效声明。
您还需要一行,
Mymap::iterator it;
if ( (it = m.find(name)) != m.end())
return it->second;
但是最好写
Mymap::iterator it = m.find(name);
if ( it != m.end() )
return it->second;
你可以将return
行放在if
之后,如果你真的想要这一行,至少对我来说这不会损害可读性,但其他人可能会看到不同。
如果你真的,真的想声明一个迭代器并在if
条件下使用它作为bool,你可以做
if ( struct { int it; operator bool() { return it != m.end; } } s = { m.find(name) } )
return s.it->second;
但我认为这有害; - )
答案 3 :(得分:0)
你无法写
这是真的if ( (int i=f()) == 0)
但你可以完美地写
if ( int i=f())
因此,您可以使用&&
运算符在一个语句中执行这两个操作,例如
if ( int i=1 && (i=f()) == 0)
i
应使用0以外的任何值进行初始化,如果编译器应用从左到右的评估,它应该是第一个条件。
但不幸的是,如果您的第二个例子要求使用迭代器,则不适用。