Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

point of instantiation and name binding

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?

like image 352
Shane Nian Avatar asked Jan 08 '23 07:01

Shane Nian


1 Answers

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 not f(double), so overload resolution resolves to f(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 of f taking this type, ADL will be able to 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) is called because it is located in the global namespace, and A's associated namespace set is the global namespace.

like image 149
David G Avatar answered Jan 17 '23 23:01

David G