2

File A.hpp:

struct foo
{
   int x;
} foo;

inline bool operator ==(const foo &lhs, const foo &rhs)
{
   /* ... */
}

File B.hpp

#include "A.hpp"

namespace SomeNamespace
{
   bool operator==(const foo &lhs, const foo &rhs)
   {
      /* ... */
   }

   /* ... */
   void someFunction(const foo &foo_instance1, const foo &foo_instance2)
   {
      CPPUNIT_ASSERT(foo_instance1 == foo_instance2);
   }
}

The compiler error for the line with the ASSERT is:

error: ambiguous overload for 'operator==' ...

So, the problem is that the compiler sees both comparison operators.

The definition in the global namespace of A.hpp and the definition in the SomeNamespace of B.hpp are ambiguous.

Why does the compiler not use the defintion in the SomeNamespace?

4
  • 3
    SSCCE or it didn't happen. Commented Sep 12, 2013 at 12:11
  • 1
    And foo_instance1 is....? Please try to provide an SSCCE when asking a question. Commented Sep 12, 2013 at 12:12
  • Sorry, corrected with edit. Commented Sep 12, 2013 at 12:22
  • And where is foo declared? Commented Sep 12, 2013 at 12:24

2 Answers 2

2

You've defined the same function twice; what do you expect to happen? The compiler finds SomeNamespace::operator== with unqualified name lookup, and ::operator== with ADL. Since both have exactly the same signature, there is no way for the compiler to choose one over the other.

As a general rule, overloaded operators for a type should be defined in the same namespace as the type, and no where else. (If the overloaded operator takes two different types, defined in two different namespaces, I'd put the operator in the global namespace. But such cases are rare.)

Sign up to request clarification or add additional context in comments.

8 Comments

I didn't know ADL also looks in global scope (if that's what you mean?).
@JamesKanze Can you explain the difference, please: with struct and with namespace?
Ok, is see that ADL is the actual "problem" since foo and its == operator are defined in the same(global) namespace. So this definition is considered as also the definition in the "local" namespace. Thx
@PetrBudnik The difference in what?
@jrok ADL looks in namespaces implied by the arguments; in this case, it looks in the global namespace because that's where foo was defined.
|
2

In your program operator== is defined in Global namespace and Somenamespace.

So when you are trying to access the operator== then compiler is unable to resolve which function to call, as both functions have same signature ans both are visible to compiler.

So to use operator== defined in SomeNamespace you must use SomeNamespace::operator== and for the operator define in Global namespace you must use ::operator==.

11 Comments

What are the lookup rules? I thought that the operator== in SomeNamespace is considered first since it should be found first.Isn't it that the compiler searches for names in a bottom-up-like manner(of the namespaces) and stops when the first correct definition is found?
its not about top-to-bottom or bottom-up. When you are compiling the code compiler has both the functions visible "at same time".
@shobi Can you explain the difference, please: with struct and with namespace?
@PetrBudnik sorry i didnt get u.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.