In the following code the bad method fails to compile, but the good method does not. Why is providing the explicit reference to this making a difference here?
#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;
}
compile error:
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_);
You can play with the ideone if you want.
This is an instance of the most vexing parse. The parentheses here don't do what you think they do. This:
std::lock_guard<std::mutex>(lock_);
is equivalent to:
std::lock_guard<std::mutex> lock_;
which should make it clear why what you're trying to do won't compile, and why you're getting the compile error you're getting. What you need to do is provide a name for the lock_guard:
std::lock_guard<std::mutex> _(lock_);
The good version works because the this-> qualification prevents the name from being able to be treated as an identifier.
Note: lock_ is a std::mutex and not any kind of lock, which makes it a very confusing name. You should name it something more reflective of what it is. Like mutex_.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With