Problem in understanding a point in argument-dependent lookup

91 views Asked by At

I have this simple example to clarify my problem:

struct S;

namespace A{
    void f(S&&) {};
    namespace B{
       struct S{};
    }
}

int main(void) {
    f(A::B::S()); 
}

This program is ill-formed since it can't find the name f by argument-dependent lookup.

But cppreference states the following:

Argument-dependent lookup, also known as ADL, or Koenig lookup 1, is the set of rules for looking up the unqualified function names in function-call expressions, including implicit function calls to overloaded operators. These function names are looked up in the namespaces of their arguments in addition to the scopes and namespaces considered by the usual unqualified name lookup.

Per my understanding of the above wording, I see that namespace A is looked up by unqualified lookup, so when ADL searches for the function name f, the namespace A has to be examined in addition to namespace A::B. So why ADL does not search for f in A? Does namespaces A is considered by the usual unqualified name lookup? Am I understand the bold part correctly?

1

There are 1 answers

3
YSC On

Not quite.

These function names are looked up in the namespaces of their arguments in addition to the scopes and namespaces considered by the usual unqualified name lookup.

  • "These function names": f in your case.
  • "in the namespaces of their arguments": A::B in your case as this function (whose name is still to be looked up) is called with an argument whose type is A::B::S.
  • "the scopes and namespaces considered by the usual unqualified name lookup": this is the global namespace as well as the "current" namespace.

In conclusion:

f(A::B::S());  // wont find A::f
f(::S());      // wont find A::f

namespace N
{
    class C{};
    void g(C) {}
}
g(N::C{});     // will find N::g through ADL via the namespace of g's argument