【发布时间】:2014-09-15 18:31:06
【问题描述】:
注意:以下内容同样适用于 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 的正确包装是什么?
编辑:所以@Praetorian 已经非常正确地解释了我的错误,但是,在 Boost 或标准上真的没有这样的东西(这里可能有错误):
template<typename T>
struct as_callable {
T &objref;
as_callable(T &r) : objref(r) {}
T &operator()() {
return objref;
}
};
【问题讨论】:
-
std::ref返回一个引用包装器。 Boost Phoenixref返回一个 functor。我想你可能混淆了这两者(见我的回答) -
while (!b) { c.wait(lock); }比c.wait(lock, []{ return b; });更具可读性,并且语义相同。当b是需要捕获的本地 (c.wait(lock, [&]{ return b; });) 或成员变量 (c.wait(lock, [this]{ return b; });) 时,lambda 变得更糟糕,但显式版本保持不变。
标签: c++ multithreading c++11 boost reference-wrapper