Consider the following C++ program
template<class T>
struct C;
template<class T>
struct B{
void f(){
cout << "a=" << C<T>::a << endl;
}
};
template<class T>
struct C{static const int a = 1;};
int main()
{
B<int> b;
b.f();
return 0;
}
g++ and clang++ think it as a right C++ program. Ok, C<T>::a should be a dependent name and compiler will look up it in instantiation(i.e., when b.f() is called).
What puzzles me is that cppreference says ADL is used for function call expression, so if here ADL does not kick in, how compiler find the declaration of a?
I have tried the following program and it shows ordinary lookup in definition can't find the declaration of a?
#include <iostream>
using namespace std;
class D;
struct E{
void f(){
cout << D::a << endl; // error: incomplete type ‘D’ used in nested name specifier
}
};
class D{
static const int a = 7;
};
int main()
{
E e;
e.f();
return 0;
}
First, after reading relevant passage in Standard that Igor Tandetnik quoted. I think it can't be used to explain my question.
[temp.dep.type]/8 said
Standard also gives a example
Here
mandthis->minf()andg()refers to a member of the current instantiationC<T>::A::m(becauseAis a non-dependent base class).So, based on this rule,
this->mwill be looked up again in template instantiation context and findB::m, error raises. Butming()is not a qualified-id or class member access expression, sotemplate int C<B>::g();is safe.Back to my example that puzzles me,
C<T>::ais actually a member of an unknown specialization. [temp.dep.type]/6:The awkward thing is that I only find the lookup rules for function name in the standard. I'd like to think compiler just do a usual lookup for dependent name which is not a function name in template instantiation context.
About point of instantiation, [temp.point]/4 say
So, point of instantiation of
template struct Cis beforetemplate struct BandC<T>::acan be accessed.But intuitive explanation "The name
agets resolved whenB<T>::f()gets instantiated" of NathanOliver may be enough for daily programming.