Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error calling user-defined operator+ on temporary object when there are extra brackets

If I have a user-defined operator+() as in:

    class A
    {
    public:
        A operator+(A)
        {
            return A();
        }
    };

Then the following works as expected:

    A a = A() + A();

but g++-4.7 gives an error message on the following:

    A a = (A()) + A();

The error message in particular is error: no match for ‘operator+’ in ‘+A()’.
It looks like the (A()) is being ignored in the expression.

My question is: is A a = (A()) + A(); supposed to compile and if not, why not?

Note: this happened to me when I did #define X (Identity()) and then tried doing X + X.

like image 531
SirGuy Avatar asked May 20 '13 03:05

SirGuy


1 Answers

It's a cast syntax.

The reason for that is that casting and the unary addition, subtraction and multiplication (the dereference operator) have higher precedence than their binary counterparts. Since the white spaces here don't matter this can also be read as:

    A a = (A()) +A(); 

The cast and unary+ have higher precedence than the binary operator+ so the expression takes the former meaning.

You might be wondering (as I did) how you can cast when the thing inside is not a type. Enter THE MOST VEXING PARSE!, which means I am trying to cast an object of type +A() to a function taking 0 arguments and returning an object of type A.

For the record, the syntax:

    A a = ((A())) + A(); 

gives what you want since the double brackets can't be a cast and we're back to parsing the binary operator+ expression.

This also explains why the problem doesn't occur with the division operator instead of the addition, it doesn't have a unary counterpart.

like image 175
SirGuy Avatar answered Oct 26 '22 19:10

SirGuy