Here is an example of an idiom with limited visibility with a common error: a local variable is not created, so the lock does not work. This code compiles perfectly with both VC ++ 2010 and Comeau C ++ on the Internet:
class Mutex { public: void lock() {} }; class ScopedLock { public: ScopedLock() : m_pm(0) {} ScopedLock(Mutex& m) : m_pm(&m) { m_pm->lock(); } private: Mutex* m_pm; private: ScopedLock& operator =(const ScopedLock&); ScopedLock(const ScopedLock&); }; class X { public: void foo() const { ScopedLock(m_mutex); } private: Mutex m_mutex; }; int main() { X x1; x1.foo(); }
If the default constructor for ScopedLock is commented out, then both compilers throw an error:
error C2512: 'ScopedLock': no suitable default constructor exists
(When ScopedLock used correctly, i.e. a local variable is created: ScopedLock guard(m_mutex); compilation fails. Declaring m_mutex as mutable fixes the problem.)
I have two questions:
Why is X::foo compiling? It seems that the compiler was able to somehow cast const Mutex& into Mutex& .
What role does the default constructor of ScopedLock , so ScopedLock compilation succeed?
Thanks.
Update: I found the answer. It looks like the ScopedLock(m_mutex); creates a local variable m_mutex type ScopedLock . Not temporary. Therefore, the ScopedLock::ScopedLock constructor of ScopedLock::ScopedLock is required.
source share