Const correctness with temporary instances
<p>Here is the example of the "scoped lock" idiom with common mistake: no local variable is created, so lock is not in effect. This code compiles flawlessly both with VC++ 2010 and Comeau C++ online:</p>

<pre><code>class Mutex
{
public:
    void lock() {}
};

class ScopedLock
{
public:
    ScopedLock() : m_pm(0) {}
    ScopedLock(Mutex&amp; m) : m_pm(&amp;m) { m_pm-&gt;lock(); }

private:
    Mutex* m_pm;

private:
    ScopedLock&amp; operator =(const ScopedLock&amp;);
    ScopedLock(const ScopedLock&amp;);
};

class X
{
public:
    void foo() const
    {
        ScopedLock(m_mutex);
    }

private:
    Mutex m_mutex;
};


int main()
{
    X x1;
    x1.foo();
}
</code></pre>

<p>If default constructor for ScopedLock is commented out, then both compilers give an error:</p>

<blockquote>
  <p>error C2512: 'ScopedLock' : no appropriate default constructor available</p>
</blockquote>

<p>(When <code>ScopedLock</code> used correctly, i.e. local variable is created: <code>ScopedLock guard(m_mutex);</code>, then compilation fails as expected. Declaring <code>m_mutex</code> as mutable fixes the problem.)</p>

<p>I have two questions:</p>

<ol>
<li><p>Why <code>X::foo</code> compiles? It seems that compiler was able to cast <code>const Mutex&amp;</code> to <code>Mutex&amp;</code> somehow.</p></li>
<li><p>What role plays <code>ScopedLock</code> default constructor, so the compilation succeeds?</p></li>
</ol>

<p>Thanks.</p>

<p><strong>Update:</strong> I found the answer. It appears that <code>ScopedLock(m_mutex);</code> statement creates a local variable <code>m_mutex</code> of type <code>ScopedLock</code>. Not a temporary. That's why <code>ScopedLock::ScopedLock</code> default constructor is required.</p>
