Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't C++ complain about multiple definitions of an operator function? [duplicate]

Tags:

c++

The following code has 2 definitions of operator+ - one is on the class Foo, and the other one is a standalone function.

I feel like the compiler should have complained about this, but it didn't. When I use operator+ in the main function, it picks the one defined in the class. When I delete the one in the class, it starts using the standalone function.

The fact that deleting a class method silently changes the behavior of the C++ program is very concerning. Is there a rationale behind this?

https://ideone.com/rtfEFP

#include <iostream>

class Foo
{
public:
    int operator+(const Foo& b)
    {
        return 5;
    }
};

int operator+(const Foo& a, const Foo& b)
{
    return 6;
}

int main()
{
    Foo a, b;
    int c{ a + b };
    std::wcout << c << std::endl;
    return 0;
}
like image 884
Shivanshu Goyal Avatar asked Feb 16 '18 06:02

Shivanshu Goyal


2 Answers

The two signatures don't really match because the first takes a non-const reference for the first operand. To "fix" this, make it const:

int operator+(const Foo& b) const

or make the first parameter of the non-member non-const (don't do that in real code!)

int operator+(Foo& a, const Foo& b)

That will cause your code to produce an ambiguous overload compiler diagnostic.

With your original code, the member is picked, because the non-const reference matches the operands better.

like image 121
juanchopanza Avatar answered Nov 19 '22 07:11

juanchopanza


This is analogous to overloads based on const and non-const qualifiers.

int operator+(const Foo& a, const Foo& b)
{
    return 6;
}

is like a const member function.

Given

Foo a;
Foo const b;
Foo c;

a + c; // Resolves to the non-const member function.

b + c; // Resolves to the non-member function since the first argument
       // is of type `const Foo&`.
like image 2
R Sahu Avatar answered Nov 19 '22 08:11

R Sahu