在if语句的条件部分定义变量?

Kir*_*rov 69 c++ variables standards if-statement

我很震惊,这是允许的:

if( int* x = new int( 20 ) )
{
    std::cout << *x << "!\n";
    // delete x;
}
else
{
    std::cout << *x << "!!!\n";
    // delete x;
}
// std:cout << *x; // error - x is not defined in this scope
Run Code Online (Sandbox Code Playgroud)

那么,这是标准允许的还是只是编译器扩展?


PS由于有几条评论 - 请忽略这个例子是"坏"或危险的.我知道.这只是我想到的第一件事,作为一个例子.

pb2*_*b2q 73

从C++ 98开始,规范允许这样做.

从第6.4节"选择陈述":

由条件中的声明引入的名称(由类型说明符-seq或条件的声明符引入)在其声明范围内,直到由条件控制的子语句结束.

以下示例来自同一部分:

if (int x = f()) {
    int x;    // ill-formed, redeclaration of x
}
else {
    int x;    // ill-formed, redeclaration of x
}
Run Code Online (Sandbox Code Playgroud)

  • 天哪!我刚刚意识到(感谢这句话),名字也在'else`的范围内.不知怎的,我一直以为它只会在`if`部分提供...... (16认同)

小智 18

它是标准的,即使在旧的C++ 98版本的语言中:

在此输入图像描述


Mat*_* M. 18

不是一个真正的答案(但评论不适合代码示例),更多的原因是它非常方便:

if (int* x = f()) {
    std::cout << *x << "\n";
}
Run Code Online (Sandbox Code Playgroud)

每当API返回"选项"类型(也恰好具有可用的布尔转换)时,可以利用这种类型的构造,以便只能在使用其值合理的上下文中访问该变量.这是一个非常强大的习语.

  • @Martin:通过选项类型,我的意思是像指针(或`boost::Optional`)这样的类型有一个“哨兵”值来表示没有实际值。如果它们还提供了到 bool 的转换,其值仅取决于类型中是否存在实际值,那么该习惯用法就有效。例如: `if (boost::optional&lt;int&gt; x = f()) { std::cout &lt;&lt; *x &lt;&lt; '\n'; }` 也有效。 (2认同)

Die*_*ühl 7

在的条件部分变量的定义while,ifswitch声明都是标准配置.相关条款是6.4 [stmt.select]第1段,它定义了条件的语法.

顺便说一下,你的使用是没有意义的:如果new失败则抛出std::bad_alloc异常.

  • 这只是一个例子.我知道,这很糟糕.这只是我想到的第一件事. (3认同)