标准如何定义在评估if
条件表达式期间构造的临时对象的生命周期?
我查找了这些信息,并在一个示例中找到了与第 10 页 1.9 美元中的 [10] 类似的内容。(我在这里指的是新规范的最终草案。)但对我来说仍然不清楚(足够)由于 Visual C++ 的行为与我对那个例子的理解不同,我决定问。
请提供适当的规范参考。
如果您命名该对象,它会在整个过程中持续存在if
(因此既是true
块又false
是块,但在结束前被销毁if
)。
例如:
if ( MyClass x = f() ) { /* ... */ } else { /* ... */ }
nextInstruction();
x
可以在两个if
块中使用,但在nextInstruction
被调用之前被破坏。
但是,如果你不命名呢?
if ( f() ) { /* ... */ } else { /* ... */ }
nextInstruction();
在我对规范的引用部分的理解中,返回的值f()
将在执行进入其中一个块( fortrue
或 for false
)之前被销毁。
但是,Visual C++ 会破坏该临时对象,就好像它已被命名一样。(编辑:正如 Tino Didriksen 指出的那样,Visual C++ 在这里工作得很好。事实上,现在我也确认了这一点。在查看初始测试结果时我一定犯了一个错误!)
这在某些极端情况下确实很重要(这里不讨论它们的可能性有多大,或者以这种方式编写代码是否好......)。
例如让我们有:
class ScopedLock {
public:
~ScopedLock() { if ( isLocked() ) unlock(); }
operator bool() const { return isLocked(); }
/* ... */
};
现在,如果我们有如下代码:
if ( ScopedLock lock = resource.lock() ) { /* ... */ }
我们可以确定,当执行进入true
块时,我们拥有该资源,并且在我们离开该块之前它不会被解锁。
但是如果有人这样写怎么办:
if ( resource.lock() ) { /* ... */ }
现在至关重要的是,临时的析构函数ScopedLock
将被调用。因为它决定了这段代码是否正确(在资源使用方面)。(再次让我们跳过讨论编写这样的代码是否不好。这不是这个问题的重点......)