注意:以下内容同样适用于Boost.Thread和C ++ 11线程。
我有一个条件变量,该条件实际上是一个简单的布尔变量。
// assume these are global
mutex m;
condition_variable c;
boolean b = false;
我想使用wait(lock, predicate)
语法。我可以使用例如lambda:
c.wait(lock, [] () { return b; });
但我认为应该有一种更惯用的方式将变量包装为可调用的。所以我发现reference_wrapper
提供了一个operator()
来检索包装的值。所以我试过了:
c.wait(lock, cref(b));
但是g ++(4.9.1)没有编译它,争论no matching function for call to '(boost::reference_wrapper<const bool>) ()'
(如果我使用std::ref
错误有些不同,但仍然没有编译)。
reference_wrapper
不应该有资格作为条件变量的正确谓词吗?如果没有,为什么?在这种情况下,b
的正确包装是什么?
template<typename T>
struct as_callable {
T &objref;
as_callable(T &r) : objref(r) {}
T &operator()() {
return objref;
}
};
答案 0 :(得分:1)
std::reference_wrapper::operator()
仅在reference_wrapper
存储可调用时才可用,而bool
不是{\ n}。使用lamdba作为谓词。
如果在与条件变量等待的线程不同的线程中修改布尔值,也可以考虑使用std::atomic_bool
而不是普通的bool
。
如果你真的想使用包装器而不是lambda,你可以编写一个重载operator()
的简单包装类,并在调用时返回存储的布尔值。
struct bool_wrapper
{
bool_wrapper(bool& b) : b_(&b) {}
bool *b_;
bool operator()() const noexcept { return *b_; }
};
现在您可以使用此类来包装布尔值并将其作为
传递给condition_variable::wait
c.wait(lock, bool_wrapper(b));
答案 1 :(得分:1)
除了恰当地解释出现问题的另一个答案之外,我想我可能能够解释 你是如何做出错误的期望的。
瞧,还有Boost Phoenix的版本ref()
和cref()
,令人惊讶地将这个参考作为凤凰懒惰演员提供。即:phx::ref()
和phx::cref()
是仿函数!
这意味着你可以简单地使用
c.wait(lock, phx::cref(b));
你可能在过去的某个地方遇到过它。