Как стандарт определяет время жизни временного объекта, построенного при оценке выражения условия if
?
Я искал эту информацию и нашел что-то подобное в примере, чтобы указать [10] в $1.9, стр. 10. (Я имею в виду здесь Final Draft новой спецификации.) Однако все же это было неясно (достаточно ) для меня, и поскольку Visual С++ действовал иначе, чем мое понимание этого примера, я решил спросить.
Просьба указать правильные ссылки на технические характеристики.
Если вы назовете объект, он сохраняется для всего if
(так что блок true
и false
блокируется, но уничтожается до окончания if
).
Например:
if ( MyClass x = f() ) { /* ... */ } else { /* ... */ }
nextInstruction();
x
может использоваться в обоих блоках if
, но уничтожается до вызова nextInstruction
.
Но что, если вы его не назовете?
if ( f() ) { /* ... */ } else { /* ... */ }
nextInstruction();
В моем понимании ссылочной части спецификации значение, возвращаемое f()
, будет уничтожено до того, как выполнение вступит в один из блоков (либо для true
, либо для false
).
Однако Visual С++ уничтожает этот временный объект, как если бы он был назван. ( EDIT:, как сказал Тино Дидриксен, Visual С++ здесь хорошо работает. И действительно, теперь я подтверждаю это также. Я, должно быть, ошибся при просмотре результатов начальных тестов!)
Это имеет значение в некоторых случаях кросс (не обсуждайте здесь, насколько они вероятны, или хорошо писать код таким образом...).
Например, давайте:
class ScopedLock {
public:
~ScopedLock() { if ( isLocked() ) unlock(); }
operator bool() const { return isLocked(); }
/* ... */
};
Теперь, если у нас есть код вроде:
if ( ScopedLock lock = resource.lock() ) { /* ... */ }
мы можем быть уверены, что, когда выполнение входит в блок true
, мы владеем ресурсом и что он не будет разблокирован, прежде чем мы покинем этот блок.
Но что, если кто-то написал это вот так:
if ( resource.lock() ) { /* ... */ }
Теперь важно, в какой момент будет вызван деструктор временного ScopedLock
. Потому что он определяет, является ли этот код правильным или нет (в смысле использования ресурсов). (Опять же, давайте пропустим обсуждение того, плохо ли пишет такой код вообще. Это не вопрос этого вопроса...)