I am confused about the point of instantiation with the following example:
#include <iostream>
void f(int){std::cout<<"int"<<std::endl;}//3
template <typename T>
void g(T t)
{
f(t);//4
}
void f(double){std::cout<<"double"<<std::endl;}
int main()
{
g<int>(1);//1.point of instantiation for g<int>
g<double>(1.1);//2.point of instantiation for g<double>, so f(double) is visible from here?
return 0;
}
I though f is a dependent name and 1. is the point of instantiation for g< int > and 2. is the point of instantiation for g< double >, so f(double) is visible for g(1.1), however the output is
int
int
and if I comment the declaration of f(int) at 3, gcc reports an error (not surprise) and points out f(t) at 4 is the point of instantiation(surprised!!).
test.cpp: In instantiation of ‘void g(T) [with T = int]’:
test.cpp:16:10: required from here
test.cpp:9:5: error: ‘f’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
f(t);
^
Can anyone clear the concept of point of instantiation and name binding for me please?
f(t)
is a dependent unqualified function call expression, so only functions found within the definition context and those found via ADL are candidates.f(int)
is visible within the definition context, but notf(double)
, so overload resolution resolves tof(int)
for both calls.f(double)
cannot be found by ADL because built-in types have no associated classes or namespaces. If you passed in an argument of class type, and there was an overload off
taking this type, ADL will be able to find it. For example:f(A)
is called because it is located in the global namespace, andA
's associated namespace set is the global namespace.