Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling constructor with a temporary object

I don't understand the following problem.

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;
}

The complete error message is (Visual Studio 2010)

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

The fix is simple:

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

    return 0;
 }

Is this a MSVC specific problem, and if not could someone explain what quirk of the language prevents me calling Box box(InnerBox()); ?

like image 574
Zero Avatar asked Dec 09 '22 22:12

Zero


1 Answers

You need to write it as:

Box box((InnerBox()));

or

Box box{InnerBox()};

This is not an MSVC specific problem. The rule in C++ is to consider any construct that could possibly be a declaration a declaration.

Without the additional parentheses, the code is declaring a function called box which returns a Box, and whose single argument is a pointer to a function taking no arguments and returning an InnerBox. (Yes -- InnerBox() actually declares a pointer to a function (not named), when used in a function parameter (this is similar to how Box[] actually declares a pointer to Box when used as a function parameter)).

like image 51
Mankarse Avatar answered Dec 29 '22 00:12

Mankarse