如果条件在内部声明变量有什么问题?

dav*_*vka 17 c++ syntax variable-declaration

也许我生锈了(最近用Python编写).

为什么这不编译?

if ( (int i=f()) == 0)
Run Code Online (Sandbox Code Playgroud)

没有我()周围的int i=f()另一个,更合理的错误i是不是布尔.但这就是为什么我首先想要括号!

我的猜测是使用括号使其成为表达式,并且表达式中不允许使用声明语句.是这样吗?如果是的话,它是C++的语法怪癖之一吗?

顺便说一下,我实际上是想这样做:

if ( (Mymap::iterator it = m.find(name)) != m.end())
    return it->second;
Run Code Online (Sandbox Code Playgroud)

Die*_*ühl 38

您可以if在C++ 中的语句中声明一个变量,但它仅限于与直接初始化一起使用,并且需要转换为布尔值:

if (int i = f()) { ... }
Run Code Online (Sandbox Code Playgroud)

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
...
Run Code Online (Sandbox Code Playgroud)

也就是说,也可以写:

if (int i{f()}) { ... }
Run Code Online (Sandbox Code Playgroud)

显然,这仅适用于C++ 2011,因为C++ 2003没有大括号初始化.

  • 从您的第一句话开始,“但是它只能用于直接初始化*,并且需要将其转换为布尔值*”->您能用简单的句子解释一下吗?(我猜初始化的值可以用作布尔值,对吗?但是从第一行也无法理解限制部分),谢谢 (2认同)

Ily*_*gan 20

范围有问题.

请考虑以下代码:

if ((int a = foo1()) || (int b = foo2()))
{
    bar(b);
}
Run Code Online (Sandbox Code Playgroud)

b是否在块内声明?如果foo1()返回true会怎么样?

  • @SoapBox但是如果foo1返回1并且通过短路评估(据我所知保证),跳过`b`的赋值怎么办? (3认同)

Gun*_*iez 5

您可以在if语句中(或在for或while中)声明变量,但只能在外部括号块中声明它,并且必须能够将其转换为bool。

您的猜测基本上是正确的,这是不允许的,因为

(int i = 42;)
Run Code Online (Sandbox Code Playgroud)

不是带有初始化的有效声明。

您需要多一行,

Mymap::iterator it;
if ( (it = m.find(name)) != m.end())
    return it->second;
Run Code Online (Sandbox Code Playgroud)

但是最好写

Mymap::iterator it = m.find(name);
if ( it != m.end() ) 
    return it->second;
Run Code Online (Sandbox Code Playgroud)

您可以将其放置在return后面if,如果您确实希望返回该行,至少对我而言,这不会损害可读性,但是其他人可能会有所不同。

如果您确实要声明一个迭代器并将其用作if条件中的布尔值,则可以执行

if ( struct { int it; operator bool() { return it != m.end; } } s = { m.find(name) } )
    return s.it->second;
Run Code Online (Sandbox Code Playgroud)

但我认为这是有害的;-)