Время жизни объекта, объявленного во втором «параметре» оператора «for» - PullRequest
0 голосов
/ 26 октября 2018

Я только что обнаружил, что объявление можно разместить и во втором «параметре» оператора for. Но я нигде не смог найти, как он ведет себя в отношении строительства / разрушения объекта, объявленного в этом параметре.

Давайте получим простой код:

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 голосов
/ 26 октября 2018

Подумайте просто, если я разработчик языка, следующие утверждения:

for ( a; b; c ) d

и

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

Должен быть строго эквивалентен

Очевидно, что некоторые переменные, определенные в a, могут использоваться в b, c, d, поэтому только a является особенным.

КСТАТИ

Я думаю, что утверждение в Скала прекраснее. В Scala for это просто синтаксический suger:

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

Где

i => s

- это синтаксис ламбы, например:

[](auto i){ s }

в C ++ 11

Это универсальная истина, переменная v любого типа, которая определяет функцию foreach, может использоваться в операторе for.

0 голосов
/ 26 октября 2018

Время жизни объекта, созданного в условии цикла, привязано к области видимости тела цикла и может также использоваться в выражении итерации (i++ в вашем примере).Условие оценивается в начале каждой итерации , создаваемый им объект длится до конца этой итерации, затем уничтожается и создается снова для следующей итерации и так далее.break или continue операторы не влияют на время жизни объекта, созданного в условии.

Причина заключается в следующем.Из [stmt.for] мы можем видеть, что цикл for определен в терминах цикла while.

Оператор for

for ( init-statement condition ; expression ) statement

эквивалентно

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

Переход к [stmt. while] и ответ на ваш вопрос (выделено мое):

Когда условием оператора while является объявление, область действия объявленной переменной простирается от точки ее объявления ([basic.scope.pdecl]) до конца оператора while.Оператор while, условие которого является инициализированным объявлением некоторой переменной t, эквивалентен

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

[Примечание: Переменная, созданная в условии, уничтожается и создается при каждой итерации цикла ,[...]]

...