Search code examples
c++namespacesfunction-callargument-dependent-lookup

Ambiguity between function and function in namespace with same argument


Can anybody explain why there is an ambiguity between A::f(const B& b) and f(const A::B& b). I consider the code to be quite explicit about the intention.

#include <iostream>

namespace A
{
  class B
  {
  protected:
    double value_;
  public:
    B() : value_(15.0) {}
    double getValue() const {return value_;}
  };

  void f(const B& b)
  {
    std::cout << "f(b) = " << b.getValue() << std::endl;
  }
}

void f(const A::B& b)
{
  std::cout << "Other f(b) = " << b.getValue() << std::endl;
}

int main()
{
  A::B b;
  A::f(b);
  f(b);
  return 0;
}

However, both g++ 7.5.0 and clang 6.0.0 complain about ambiguous function call (error: call of overloaded ‘f(A::B&)’ is ambiguous) regardless of compiler flags and optimizations.


Solution

  • This is an example of argument-dependent lookup.

    Even though ::main is in global namespace, A::f is callable without using the fully-qualified name, because it is looked up in the namespace A of its argument, A::B. As a result, there is an ambiguity between ::f and A::f.

    To resolve the ambiguity, you would need to call either A::f(b) (as you did), or ::f(b).