C ++ 11: На основе диапазона для оператора: время жизни "range-init"? - PullRequest
18 голосов
/ 11 марта 2012

В последнем стандарте C ++ это означает, что:

for (foo : bar)
    baz;

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

{
    auto && r = bar;
    for ( auto it = r.begin(), end = r.end(); it != end; ++it )
    {
        foo = *it;
        baz;
    }
}

Когда в приведенном выше баре есть вызов функции, который возвращает коллекцию, например:

vector<string> boo();

е

for (auto bo : boo())
    ...

Разве строка не становится:

auto&& r = boo();
...

И поэтому временное возвращаемое значение boo () уничтожается в конце инструкции auto && r = boo (), а затем r является зависающей ссылкой на вход цикла ?? Это рассуждение правильно? Если нет, то почему нет?

Ответы [ 2 ]

16 голосов
/ 11 марта 2012

Правильно ли это рассуждение? Если нет, то почему?

Это верно до этого момента:

И поэтому временное возвращаемое значение boo () уничтожается в конце инструкции "auto && r = boo ()" [...]

Привязка временного объекта к ссылке продлевает срок его службы до срока действия ссылки. Таким образом, временное действие длится для всего цикла (поэтому также существует дополнительный набор {} вокруг всей конструкции: для правильного ограничения времени жизни этого временного объекта).

Это соответствует пункту 5 §12.2 стандарта C ++:

Второй контекст - это когда ссылка связана с временным. временный, к которому привязана ссылка, или временный, который является завершенный объект подобъекта, к которому привязана ссылка сохраняется в течение всего срока действия ссылки, кроме:

[различные исключения, которые здесь не применяются]

Это интересное свойство, которое позволяет злоупотреблять циклическим циклом для вещей, не относящихся к диапазону: http://ideone.com/QAXNf

6 голосов
/ 11 марта 2012

Причина неверна, потому что boo возвращает временный объект по значению.Привязка этого временного объекта к ссылке подразумевает, что время жизни временного объекта увеличивается.Стандартная цитата (§ 12.2 / 5):

[…] Временный объект, к которому привязана ссылка, или временный объект, являющийся полным объектом подобъекта, к которому привязана ссылка, сохраняется в течение всей жизни.ссылки […]

Аргументация будет правильной, если boo вернет ссылку.Примером выражения, возвращающего ссылку на временный объект, является string("a") += string("b");использование этого значения в цикле for на основе диапазона приводит к неопределенному поведению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...