我正在尝试使用RAII来创建在流上行动的对象,直到它们被销毁。例如,每当添加endl
时,我都会有一个自动刷新的流。大部分时间我都想要这个,但并非总是如此。我希望能够说“不要在endl上刷新”,但我也需要它是异常安全的。所以我不能只stream->NoFlush()
设置一个类成员。无论如何,我想知道的是这个。如果我有像
CStreamModifier no_flush;
stream->NoFlush(no_flush);
// as long as no_flush is in scope I get the behaviour I want
... do some stuff on the stream, without referencing no_flush ...
// no_flush goes out of scope here.
是否允许编译器优化no_flush的生命周期?例如,它在第2行之后没有使用,但我需要它一直保持到最后。我还没有听说过这样的任何优化,所以我觉得我没事,但我想确定一下。
答案 0 :(得分:2)
不,编译器不允许对其进行优化。当对象超出范围时,将完全调用析构函数。
如果NoFlush
按值获取参数,它可以做的是优化它的副本,但这无关紧要。
复制elision是编译器可以执行的唯一影响可观察行为的优化。
答案 1 :(得分:2)
我会这样做:
struct Stream
{
bool flush = true;
// ...
};
struct NoFlush
{
explicit NoFlush(Stream & s)
: stream(s)
, prev(stream.flush)
{ stream.flush = false; }
~NoFlush()
{ stream.flush = prev; }
Stream & stream;
bool prev;
};
现在您可以像这样使用它:
void foo(T arg, S brg, Stream & stream)
{
NoFlush _(stream);
// do stuff
}