Overload resolution resolves to a function not visible yet

c++

Solution

The answer is found via argument-dependent name lookup (ADL) (which is also mentioned in the linked question). `foo(T());` has two lookups. First at template definition time, any functions defined at the point of definition are included in the overload set. This means when the compiler sees `foo(T());` inside of `bar`, it adds only `void foo(type1 x)` to the overload set. However there is a second lookup that is performed, called ADL. At template instantiation time, i.e. `bar<type2>();` it looks for a `foo` in the same namespace as the argument which is provided, which in this case is `type2`. Since `type2` is in the global namespace, it looks for a `foo` that takes a `type2` in the global namespace and finds it, and resolves the call. If you are looking for info from the standard, see `14.6.4.2 Candidate functions`.

Try the following and watch the code fail. This is because it cannot find `foo` in the same namespace as `a::type1`.

#include <iostream>

namespace a
{
  struct type1 {};
}

template<typename T>
void bar() {
  foo(T());
}

int main()
{
  bar<a::type1>();
  return 0;
}

void foo(a::type1 x)
{
  std::cout << "foo(a::type1)" << std::endl;
}

Problem

This is kind of a follow on to this question. ``` #include <iostream> struct type1 {}; struct type2 {}; void foo(type1 x) { std::cout << "foo(type1)" << std::endl; } template<typename T> void bar() { foo(T()); } int main() { bar<type1>(); bar<type2>(); return 0; } void foo(type2 x) { std::cout << "foo(type2)" << std::endl; } ``` In the above code `foo(type2)` is not visible at the time of instantiation of `bar<type2>` in `main`. And yet the code compiles and produces the following output : ``` foo(type1) foo(type2) ``` How does the compiler know that `foo(type2)` is available when instantiating `bar<type2>` in `main`? EDIT : I am trying to understand more about how overload resolution during template instantiation works. Consider the code below : ``` #include <iostream> struct type1 {}; struct type2 {}; struct type3 { operator type2() { return type2(); } }; void foo(type1 x) { std::cout << "foo(type1)" << std::endl; } void foo(type2 x) { std::cout << "foo(type2)" << std::endl; } int main() { foo(type3()); return 0; } void foo(type3 x) { std::cout << "foo(type3)" << std::endl; } ``` The output is ``` foo(type2) ``` Even though a closer match `foo(type3)` is available, the call `foo(type3())` resolves to `foo(type2)` because that was the only candidate that has been parsed by the compiler until that point. Now consider the following code : ``` #include <iostream> struct type1 {}; struct type2 {}; struct type3 { operator type2() { return type2(); } }; void foo(type2 x) { std::cout << "foo(type2)" << std::endl; } template<typename T> void bar() { foo(T()); } int main() { bar<type3>(); return 0; } void foo(type3 x) { std::cout << "foo(type3)" << std::endl; } ``` The output is ``` foo(type3) ``` That is, at the point of the call `bar<type3>()`, even though only `foo(type2)` is visible, the compiler still picks `foo(type3)` that comes later because that is a closer match.

Original source

Related problems