在“ for”语句的第二个“参数”中声明的对象的生存期

时间:2018-10-26 07:12:01

标签: c++ for-loop destructor

我刚刚发现可以在声明的第二个“参数”中放置一个声明。但是我在任何地方都找不到关于该参数中声明的对象的构造/破坏行为的方式。

让我们使用以下简单代码:

struct C {
  C() { puts("constr"); }
  ~C() { puts("destr"); }
};

int main() {
  for (int i = 0; auto h = std::make_unique<C>(); i++) {
    puts("in");
  }
}

请告诉我h何时被销毁? (在puts("in")i++,...?之后)。 break;continue;的行为如何?

感谢您的澄清!

2 个答案:

答案 0 :(得分:5)

在循环条件内创建的对象的生命周期受循环主体范围的约束,也可以在迭代表达式(您的示例中为i++)内使用。条件在每次迭代的开始进行评估,它创建的对象一直持续到该迭代结束,然后销毁并为下一次迭代再次创建对象,依此类推。 breakcontinue语句不影响条件中创建的对象的生存期。

原因如下。从[stmt.for],我们可以看到一个for循环是根据while循环定义的。

  

for语句

for ( init-statement condition ; expression ) statement
     

等同于

{
    init-statement
    while ( condition ) {
        statement
        expression ;
    }
}

跳回到[stmt.while],然后得出您的问题的答案(强调我的意思):

  

当while语句的条件是声明时,所声明的变量的范围从其声明点([basic.scope.pdecl])扩展到while语句的末尾。条件为某些变量t的初始化声明的while语句等效于

label:
{ // start of condition scope
    condition; // declares t
    if (t) {
        statement
        goto label;
    }
} // end of condition scope
     

[注意:在条件中创建的变量会在每次循环迭代时销毁并创建。 [...]]

答案 1 :(得分:-1)

简单一点,如果我是语言设计师,则以下语句:

for ( a; b; c ) d

for ( a; { b }; { c }) { d }

应严格等效

很明显,a中定义的某些变量可以在bcd中使用,因此只有a是特殊的。

顺便说一句

我认为Scala中的陈述更美。在Scala for中,语法只是一个语法:

for (i <- v) s  <==> v.foreach(i => s)

哪里

i => s

是lamba语法,例如:

[](auto i){ s }

在C ++ 11中

这是普遍适用的,定义函数v的每种类型的变量foreach都可以在for语句中使用。