Lookup rules

void g(double) { std::cout « “g(double)\n”; }

template struct S { void f() const { g(1); // “g” is a non-dependent name, bound now } };

void g(int) { std::cout « “g(int)\n”; }

int main() { g(1); // calls g(int)

S<int> s;
s.f(); // calls g(double) } ``` # Example 2 The two examples below show that the set of candidate functions is the union of the candidates from non-ADL and ADL lookups: ```c++ #include <iostream>

namespace Foo2 { struct MyType2 {}; void h(MyType2) { std::cout « “Called Foo::h(MyType2)\n”; } }

template void g(T a) { h(a); }

namespace Foo { struct MyType {}; void h(MyType) { std::cout « “Called Foo::h(MyType)\n”; } }

int main() { g(Foo2::MyType2()); // Called Foo::h(MyType2) return 0; }

```c++
#include <iostream>

namespace Foo {
    struct MyType {};
    void h(MyType) {
        std::cout << "Called Foo::h(MyType)\n";
    }
}

template <class T>
void g(T a) {
    h(a);
}

namespace Foo2 {
    struct MyType2 {};
    void h(MyType2) {
        std::cout << "Called Foo::h(MyType2)\n";
    }
}

int main() {
    g(Foo2::MyType2()); //Called Foo::h(MyType2)
    return 0;
}

Example 3

#include<iostream>

void h(double);

template<class T> void g(T a) {
  h(a);
}

void h(double) { std::cout << "Called h(double)" << std::endl; }
void h(int) { std::cout << "Called h(int)" << std::endl; }

int main(){
   g(234); // Called h(double)
   return 0;
}
  1. When g<T> is defined, the compiler does an unqualified lookup of h. At that point, it only sees the forward declaration void h(double);.
  2. Later, when you call g(234), ADL (argument-dependent lookup) tries to find more overloads in the namespace of int, but int is a fundamental type with no associated namespace—so no new overloads are found.
  3. Thus, the only candidate is h(double), which is called, printing "Called h(double)". The h(int) overload is ignored because it wasn’t visible at g’s definition time and ADL doesn’t bring it in.