首页 > 解决方案 > 通过引用传递表达式的结果

问题描述

我有一个功能:

  int f(std::atomic<bool>& flag);

这需要检查 的值flag,这是一个被另一个线程更改的原子布尔值。如果我这样调用它,这个函数会按预期工作(f看到另一个线程对标志所做的更改):

f(m_flag1);

我现在要实现的目标稍微复杂一些,因为我不想将引用传递给单个原子 bool,而是传递给表达式,例如:

std::atomic<bool> x = m_flag1 && m_flag2;
f(x);

据我了解,直接将表达式传递给函数是错误的,因为这将是一个临时值,一旦调用函数就会被销毁。在我看来,r 值也不能作为参考传递。但是,引用 tox并没有多大帮助,因为我认为表达式只被评估一次,所以f实际上并没有看到m_flag1 && m_flag2.

什么是获取表达式引用的干净方法?我的其他线程应该不断评估x = m_flag1 && m_flag2;还是有更清洁的方法?

标签: c++referencervalue

解决方案


从问题评论:

“[...]那个函数需要检查一个布尔表达式[...]”

强调我的

如果您的函数不应该修改布尔标志而只评估其值,那么您可以只将参数作为const参考。

int f(const std::atomic<bool> & flag)
{
    // ...
}

电话可能是这样的:

int result = f(flag1 && flag2);

注意:如果您需要“同时”评估两个标志(很可能是这种情况),您需要添加一个同步机制,例如互斥锁,因为表达式评估flag1 && flag2不是原子的,无论 ifflag1flag2are。


现在,如果您的函数可能会修改标志,因此const不可能将其作为参考,那么您别无选择,只能将标志作为两个单独的参数提供并推迟函数内部的评估

再次来自问题评论:

“问题是,该函数通常只用一个标志调用,这是我需要两个标志的特殊情况”

考虑到这一点,您可以重载该函数以处理带有一个或两个参数的情况,如下所示:

int f(std::atomic<bool> & flag)
{
    // ...
}
int f(std::atomic<bool> & flag1, std::atomic<bool> & flag2)
{
    auto expr_result = flag1 && flag2; // Evaluation of the expression deferred into the function
    // ...
}

如果您想让表达式的计算成为原子的,上面关于需要同步机制(例如互斥锁)的说明仍然适用于此。


推荐阅读