检测首次通过执行

时间:2012-02-13 17:01:02

标签: c++ do-while

我有一个do-while循环,每当它的状态(例如通过/失败)发生变化时,需要记录一次消息(因此它不会使日志混乱),但是每次循环时都需要做其他事情通过循环。使用简单的布尔变量基本上可以告诉您是否已经记录了该消息,一旦您处于已知状态,该消息就会起作用。但是,如果您希望在任何一种情况下(通过/失败)第一次打印消息,您必须考虑到这一点。例如,如果您将条件默认为true,并且它实际上是第一次为真,它将不会记录它认为已经为真的“真实”消息(并且反之亦然。)

对于带有i.c. = Null的nullable布尔值来说这似乎是一个好地方,但是在那些不存在的语言中,有什么可以做的?

我能想到的最简单的解决方案是使用一个额外的布尔变量,比如'firstTime = True',但是当我觉得应该有一个更精细的方法来处理它时,使用它总是困扰我作为一个基本的解决方法。另一种选择是使用do-while的breakout条件作为你用作条件的任何变量的初始条件,但是当有人阅读int status = STATUS_QUIT时,这可能会让人感到困惑,而且肯定需要更多的解释性注释而不是bool firstTime = true。第三种选择是使用枚举而不是bool并使用{firstTime,true,false}或其他东西。

是否有其他理由使用其中一个,或者有更好的方法来做到这一点?

我提出了两个选项的代码示例:

使用bool firsttime

bool firstTime = true, infoFound = false;
do
{
    if (getInfo())
    {
        if (!infoFound)
        {
            // log it (ONCE)(important)
            infoFound = true;
        }
        // use info (every time)
    }
    else if (infoFound || firstTime)
    {
        // log it (ONCE)(important)
        infoFound = false;
        firstTime = false;
    }
// FYI, WaitForStatusUpdate is a blocking call...
} while (STATUS_QUIT != WaitForStatusUpdate());

使用while循环'分组条件'作为检查变量的初始条件:
status会在执行结束时更新,因此do部分将不会再次执行status == breakOutCondition;我们可以使用此部分我们在这里的优势并且最初设置status = breakOutContition - 第一次通过它breakOutCondition但是任何后续循环其他东西......仍然不确定我喜欢这个,因为它是一种黑客......

bool infoFound = false;
int status = STATUS_QUIT;
do
{
    if (getInfo())
    {
        if (!infoFound)
        {
            // log it (ONCE)(important)
            infoFound = true;
        }
        // use info (every time)
    }
    else if (infoFound || firstTime)
    {
        // log it (ONCE)(important)
        infoFound = false;
    }
    status = WaitForStatusUpdate();
} while (STATUS_QUIT != status);

(我将其标记为c ++,因为我正在使用它,但这确实适用于任何具有类似结构的语言)

2 个答案:

答案 0 :(得分:2)

枚举不会更清楚吗?

enum State { Unknown, Pass, Fail };
State state = Unknown;
...
State newState = getInfo() ? Pass : Fail;
if (newState != state) { log();  state = newState; }

答案 1 :(得分:1)

C ++几乎有可空的布尔值,boost::optional<bool>可以做我认为的伎俩。

在C ++中执行此操作的一种常见方法是在适当的上下文中创建的流包装器,并且它会记住例如它刷新了多少次并阻止进一步的日志记录发生。您只需正常进行日志记录,然后让流决定是否将其发送到包装的流。