尝试创建临时对象时出现奇怪的编译器错误

时间:2011-03-01 19:38:54

标签: c++ most-vexing-parse

发布this question后,我尝试在创建范围内的RAII对象时重现意外右值创建的问题。现在看来我没有编译器错误就无法重现它!

在下面的代码示例中,在Test::foo()中,第二个ScopedLock创建不会编译。 gcc编译器错误似乎完全错误。谁能解释一下?

struct Mutex
{
    void lock() { }

    void unlock() { }
};


struct ScopedLock
{
    ScopedLock(Mutex & inMutex) : mMutex(inMutex)
    { mMutex.lock(); }

    ~ScopedLock()
    { mMutex.unlock(); }

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

    Mutex mMutex;
};


struct Test
{
    void foo()
    {
        // Compiles fine
        ScopedLock lock(mMutex);

        // Error: no matching function for
        // call to ‘ScopedLock::ScopedLock()’
        ScopedLock(mMutex);
    }

    Mutex mMutex;
};

我在Mac上使用GCC 4.2.1。

更新

我查看了原始代码,发现该成员是通过this指针引用的:

ScopedLock(this->mMutex); // short-lived temporary and compiles fine

2 个答案:

答案 0 :(得分:5)

您有两个用户声明的构造函数,因此没有编译器生成的默认构造函数。

是,

Type (i);

的处理方式与

相同
Type i;

这样的括号在更复杂的声明中很有用,例如

Type (*i)();

声明指向返回类型的函数的指针。

答案 1 :(得分:0)

该消息告诉您ScopedLock没有默认构造函数,即不带参数的构造函数。如果声明一个带参数的构造函数,C ++将不会为您创建一个默认值。