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

max*_*ywb 2 c++ mutex c++11

在以下代码中,该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;
}
Run Code Online (Sandbox Code Playgroud)

编译错误:

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_);
Run Code Online (Sandbox Code Playgroud)

如果你愿意,你可以玩ideone.

Bar*_*rry 9

这是最令人烦恼的解析的一个例子.这里的括号不符合你的想法.这个:

std::lock_guard<std::mutex>(lock_);
Run Code Online (Sandbox Code Playgroud)

相当于:

std::lock_guard<std::mutex> lock_;
Run Code Online (Sandbox Code Playgroud)

这应该清楚说明为什么你要做的事情不会编译,以及为什么你得到你得到的编译错误.您需要做的是提供以下名称lock_guard:

std::lock_guard<std::mutex> _(lock_);
Run Code Online (Sandbox Code Playgroud)

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


注意:lock_是一种std::mutex而不是任何类型的锁,这使它成为一个非常混乱的名称.你应该把它命名为更能反映它是什么的东西.喜欢mutex_.

  • 只是一个侧面注释 - 编译时的第二个变体,并没有真正锁定任何有意义的时间 - 锁定在此行之后立即到期,而不是在函数结束时,这可能是期望的. (3认同)

Ben*_*igt 5

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

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

void Foo::good()
{
  std::lock_guard<std::mutex> y{this->lock_};
}
Run Code Online (Sandbox Code Playgroud)

使用临时几乎是无用的,因为锁立即被释放.正确的用法是声明具有自动生命周期的局部变量.