如何在类成员互斥上使用std :: lock_guard

时间:2015-09-29 17:44:31

标签: c++ c++11 mutex

在以下代码中,bad方法无法编译,但good方法没有。为什么在这里提供明确的this参考?

#include <mutex>

class Foo
{
 private:
  std::mutex lock_;

 public:
  Foo() = default;
  ~Foo() = default;

  void bad();
  void good();
};

void Foo::bad()
{
  std::lock_guard<std::mutex>(lock_);
}

void Foo::good()
{
  std::lock_guard<std::mutex>(this->lock_);
}

int main()
{
  return 0;
}

编译错误:

test.cpp: In member function ‘void Foo::bad()’:
test.cpp:18:36: error: no matching function for call to ‘std::lock_guard<std::mutex>::lock_guard()’
   std::lock_guard<std::mutex>(lock_);

如果需要,您可以使用ideone

3 个答案:

答案 0 :(得分:9)

这是最令人烦恼的解析的一个实例。这里的括号不做你认为他们做的事。这样:

std::lock_guard<std::mutex>(lock_);

相当于:

std::lock_guard<std::mutex> lock_;

应该清楚说明为什么你要做的事情不会被编译,以及为什么你会得到你正在获得的编译错误。您需要做的是为lock_guard提供一个名称:

std::lock_guard<std::mutex> _(lock_);

好的版本有效,因为this->限定条件阻止名称被视为标识符。

注意:lock_std::mutex而不是任何类型的锁,这使得它成为一个非常令人困惑的名称。你应该把它命名为更能反映它是什么的东西。与mutex_一样。

答案 1 :(得分:5)

如果您正确声明了lock_guard,它们都可以正常工作:

void Foo::bad()
{
  std::lock_guard<std::mutex> x{lock_};
}

void Foo::good()
{
  std::lock_guard<std::mutex> y{this->lock_};
}

使用临时工具几乎没用,因为锁会立即释放。正确的用法是声明一个具有自动生命周期的局部变量。

答案 2 :(得分:3)

您需要实际创建一个变量,例如

std::lock_guard<std::mutex> lg(lock_);