有没有办法像bool一样进行“后置开关”操作?

时间:2016-07-26 12:30:27

标签: c++ boolean

我有一个类似下面的条件,我只想让第二个bool成为一次触发器,因为这个条件相对经常被调用我不喜欢做分配的想法每次条件成立时它都是假的,所以我试图利用逻辑AND和OR以及后增量运算符的顺序。但似乎工作不做我期望它做的事情。那么有没有办法为这条线进行后置状态切换?

其中firstTitleNotSet是:

bool firstTitleNotSet;

if (titleChangedSinceLastGet() || (p_firstTitleNotSet && p_firstTitleNotSet++))

这个想法是第一部分是主触发器,第二部分是只需要第一次触发的触发器。

虽然我很容易做到

if (titleChangedSinceLastGet() || p_firstTitleNotSet)
{
    firstTitleNotSet = false;
    //...
}

我不喜欢这个,因为在调用条件块时它会重新分配。

那么从truefalse有什么方法可以“更改”bool的值吗?我知道这会相反的方式,但这会否定该方法的优点,大部分时间是真正的触发器,因此跳过以下检查。

注意:我做出这些考虑的原因不仅仅是第二种情况,即经常调用此块,因此我希望优化其消耗的运行时间。

4 个答案:

答案 0 :(得分:2)

嗯,你可以这样做:

if (titleChangedSinceLastGet() ||
    (p_firstTitleNotSet ? ((p_firstTitleNotSet=false), true):false))

另一种语法是:

if (titleChangedSinceLastGet() ||
    (p_firstTitleNotSet && ((p_firstTitleNotSet=false), true)))

任何一个看起来都有些难看。但请注意, NOT 与您的其他选择相同:

if (titleChangedSinceLastGet() || p_firstTitleNotSet)
{
    p_firstTitleNotSet = false;
    //...
}

根据您提出的替代方案,将p_firstTitleNotSet无论如何重置为false这一事实,即使条件是因为titleChangedSinceLastGet()而输入。

答案 1 :(得分:1)

orif内的三元运算符内的赋值更可读的方法就是将操作移动到它们自己的语句中:

    bool needsUpdate = titleChangedSinceLastGet();
    if(!needsUpdate && firstTitleSet)
    {
        needsUpdate = true;
        firstTitleSet = false;
    }

    if(needsUpdate)
    {
        //...
    }

这可能产生与提议的不太可读的替代方案非常相似的汇编,因为三元运算符大多只是if语句的语法糖。

为了证明这一点,我给了GCC Explorer以下代码:

首先是extern bool; bool改变了();

int f1()
{
  if (changed() ||
     (first ? ((first=false), true):false))
    return 1;
  return 0;
}

int f2()
{
  bool b = changed();
  if(!b && first)
  {
    b = true;
    first = false;
  }
  return b;
}

生成的程序集在优化后生成的程序集中只有很小的差异。当然要自己看看。

但是,我坚持认为,这不太可能在性能方面产生显着差异,而且这更多是出于利益的考虑。 在我看来:

    if(titleChangedSinceLastUpdate() || firstTitleSet)
    {
        firstTitleSet = false;
        //...
    }

是(至少)同样不错的选择。

您可以将上述功能的装配与此进行比较以进一步比较。

bool f3()
{
  if(changed() || first)
  {
    first = false;
    return true;
  }
  return false;
}

答案 2 :(得分:0)

这应该有效:

int firstTitleSet = 0;
if (titleChangedSinceLastGet() || (!firstTitleSet++))

如果你想避免溢出,你可以这样做:

int b = 1;
if (titleChangedSinceLastGet() || (b=b*2%4))

在第一次迭代b=2,而b=0在其余部分。

答案 3 :(得分:0)

在这种情况下,我经常写:

bool firstTitleNotSet = true;

if (titleChangedSinceLastGet() || firstTitleNotSet)
{
    if (firstTileNotSet) firstTitleNotSet = false;
    //...
}

第二次比较可能会被编译器优化。

但是如果您偏好后增量运算符:

int iterationCount = 0;
if (titleChangedSinceLastGet() || iterationCount++ != 0) 
{
    //...
}

请注意,如果iterationCount溢出,这将是一个问题,但对于您后续递增的bool firstTitleNotSet也是如此。

在代码可读性和可维护性方面,我会推荐前者。如果代码的逻辑是合理的,那么你可以依靠编译器来优化它,即使它看起来不那么优雅。