使用临时对象调用构造函数

Zer*_*ero 4 c++ most-vexing-parse

我不明白以下问题.

class InnerBox
{
public:
    InnerBox() : mContents(123) { };
private:
    int mContents;
};


class Box
{
public:

    Box(const InnerBox& innerBox) : mInnerBox(innerBox) { };

private:
    InnerBox mInnerBox;
};


void SomeFunction(const Box& box)
{
    return;
}

int main()
{
    Box box(InnerBox());  // !!PROBLEM!! Doesn't work: compiler thinks this is a function declaration
    SomeFunction(box);    // Error, cannot convert 'function pointer type' to const Box&

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

完整的错误消息是(Visual Studio 2010)

 error C2664: 'SomeFunction' : cannot convert parameter 1 from 'Box (__cdecl *)(InnerBox (__cdecl *)(void))' to 'const Box &'
Run Code Online (Sandbox Code Playgroud)

修复很简单:

int main()
{
    InnerBox innerBox;
    Box box(innerBox);  
    SomeFunction(box);

    return 0;
 }
Run Code Online (Sandbox Code Playgroud)

这是一个MSVC特定的问题,如果没有,有人可以解释这种语言的怪癖阻止我打电话Box box(InnerBox());吗?

Man*_*rse 5

你需要把它写成:

Box box((InnerBox()));
Run Code Online (Sandbox Code Playgroud)

要么

Box box{InnerBox()};
Run Code Online (Sandbox Code Playgroud)

这不是MSVC特定的问题.C++中的规则是考虑任何可能是声明声明的构造.

如果没有附加的括号,代码就会声明一个函数,该函数box返回一个Box,其单个参数是一个指向函数的指针,该函数不带参数并返回一个InnerBox.(是 - InnerBox()实际上在函数参数中使用时声明了一个指向函数(未命名)的指针(这类似于在用作函数参数时Box[]实际声明指针的方式Box)).

  • "最令人烦恼的解析" (3认同)

Rol*_*lie 5

原始类似被解析为名为'box'的函数的函数声明(不是定义),该函数返回Box并将函数指针作为参数,该函数指针返回InnerBox并且不带参数InnerBox (*)().见对最令人头痛的问题解析一个很好的说明.

您可以使用其他括号明确区分对象构造Box box((InnerBox()));.或者作为一个稍微更清晰的替代方法,您可以使用新的C++ 11对象构造语法:

Box box{InnerBox()};