user2953119
user2953119

Reputation:

Why does the following operator overloading is ambiguous?

In the following code:

#include <iostream>
#include <initializer_list>

struct A
{
    bool operator+(A a);
};

bool operator+(A, A)
{
    return false;
}

int main()
{ 
    A a, b;
    std::cout << a + b << std::endl;
}

DEMO

The Standard says N3797:3/8 [basic]:

Two names are the same if

— they are identifiers composed of the same character sequence, or

— they are operator-function-ids formed with the same operator, or

[...]

I this example we defined and declared two operator-functions with the same operator, therefore these two functions have the same name. Therefore the first declaration introduces the name, the second defines an entity, denoted by that name. What's wrong?

Upvotes: 1

Views: 62

Answers (2)

M.M
M.M

Reputation: 141554

In your code the two functions have the same name, operator+. However, it is possible to have different functions that have the same name. Another example is:

int foo();
int foo(int);

Those are different functions with the same name.

The relevant clauses for your code are N3936 [basic.link]/9:

Two names that are the same (Clause 3) and that are declared in different scopes shall denote the same variable, function, type, enumerator, template or namespace if

  • both names have external linkage or else both names have internal linkage and are declared in the same translation unit; and
  • both names refer to members of the same namespace or to members, not by inheritance, of the same class; and [...]

In your code, the second bullet point fails because one operator+ is a member of a class but the other one is not a member of the same class. Therefore the names denote different functions.

The case of overloaded functions in the same scope (as in my example) is covered by [dcl.fct]/5

Upvotes: 1

jwodder
jwodder

Reputation: 57470

Those two functions do not have the same name. The first one is A::operator+(A), while the second is operator+(A,A). Thus, they are two different functions, and only the second is actually defined.

After all, giving a class Foo a method named bar() is not the same as defining a function bar(Foo). Why should operators be any different?

Upvotes: 3

Related Questions