【问题标题】:Strange compiler error when trying to create a temporary object尝试创建临时对象时出现奇怪的编译器错误
【发布时间】:2011-03-01 19:38:53
【问题描述】:

在我发布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

【问题讨论】:

  • 嘿,我想知道你上一个问题的这个问题......语法意味着函数调用,而不是临时对象。您可能想问问您的同事,他的情况是否比他想象的更复杂。
  • 是的,我明天一定要去看看。
  • @Shog9 原来他使用了以下语法:ScopedLock(this->mutex);。编译得很好。

标签: c++ most-vexing-parse


【解决方案1】:

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

是的,

Type (i);

处理方式与

相同
Type i;

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

Type (*i)();

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • GCC 是正确的,确实没有默认构造函数。但是,我调用的构造函数不是默认构造函数。它采用Mutex& 参数。
    • 不,根据 gcc,您正在创建一个名为 mMutex 的 ScopedLock。添加 () ctor,然后在 ScopedLock(mMutex) 调用之后调用 mMutex.lock(),它会抱怨 ScopedLock 没有锁成员函数
    • @Erik,看来你是对的。是 GCC 错了还是我的代码非法?
    • 不通读标准,我认为 GCC 是对的。 MSVC 给出了相应的错误消息。
    猜你喜欢
    • 1970-01-01
    • 2023-03-07
    • 2013-02-25
    • 2011-03-28
    • 1970-01-01
    • 2016-01-31
    • 2014-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多