Instance creation and name binding
I am confused about the point of instantiation in 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, although f is a dependent name and 1. is the instantiation point for g <int> and 2.is the instantiation point for g <double>, so f (double) is mapped for g (1.1), however the output
int
int
and if I comment out the declaration of f (int) at 3, gcc reports an error (not surprised) and indicates that f (t) at point 4 is the instantiation point (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 up the concept of the moment of name creation and binding for me please?
source to share
f(t)
is a dependent expression of an unqualified function call, so only functions found in the context of the definition and found through ADL are candidates. f(int)
is displayed in the context of the definition, but not f(double)
, so overload resolution is allowed f(int)
for both calls.
f(double)
cannot be found by ADL because the built-in types have no associated classes or namespaces. If you passed a class type argument and there was an overload of f
that type, ADL can find it. For example:
void f(int);
template <typename T>
void g(T t)
{
f(t);
}
class A {};
void f(double);
void f(A);
int main()
{
g(1); // calls f(int)
g(1.1); // calls f(int)
g(A{}); // calls f(A)
}
f(A)
called because it is in the global namespace and the A
associated namespace is the global namespace.
source to share