1

Josuttis and Vandervoorde mentioned, that for dependent unqualified names compiler applies ordinary lookup on first phase and ADL on second. Then it combines overload set. Something like this:

struct B{};

void bar(int){} // first overload

template <class T>
void foo(T t)
{
  bar(2, t);
}

void bar(int, B){} // second overload

int main() {
    foo(B{}); // works just fine, calls second overload
}

But if dependent name is name of member function then this principle doesn't work:

struct B{};

struct A{
  template <class T>
  void foo(T t)
  {
    bar(2, t);
  }

  void bar(int){} // first overload
};

void bar(int, B){} // second overload

int main() {
  A a;
  a.foo(B{}); // gives error
}

Why is it? I was wondering if somebody could point on notes from Standard

Bikineev
  • 1,645
  • 14
  • 20
  • 2
    This has nothing to do with templates. Name lookup won't perform ADL, and won't continue to enclosing scopes if a member function is found with the name that is searched for. [Example](http://coliru.stacked-crooked.com/a/3aac0799c785afa9) – dyp Jan 19 '15 at 23:59
  • It's very inconvenient for understanding – Bikineev Jan 20 '15 at 00:09
  • 3
    (Unqualified) name lookup proceeds from the local scope to the outside. It stops whenever the name has been found in some scope A. Enclosing scopes of A then are not searched any more (the name has already been found). Then, (pure) ADL is performed - but only if either no name has been found yet, or the name(s) that has been found is *not* a member function. A member function takes priority over everything outside. – dyp Jan 20 '15 at 00:18
  • would it be related to this by any chance ? http://stackoverflow.com/questions/25031253/why-dont-methods-of-structs-have-to-be-declared-in-c/25031961#25031961 – v.oddou Jan 20 '15 at 05:14

1 Answers1

0

I found a statement in Standard 3.4.2:

Let X be the lookup set produced by unqualified lookup and let Y be the lookup set produced by argument dependent lookup. If X contains:

  • a declaration of class member, or

  • a block-scope function declaration that is not a using-declaration, or

  • a declaration that is neither a function or a function template

then Y is empty.

Bikineev
  • 1,645
  • 14
  • 20