Recently I was studying the exact meaning of the well-known "two-phase name lookup" for the names in template classes. Although I have read a lot of articles about this, I still cannot know everything about this. Now I was confusing about the code shown below:
template<typename T>
class A
{
public:
void f(T, T){};
};
namespace ns
{
typedef int TT;
void f(int, int){};
};
template<typename T>
class B : public A<T>
{
public:
void g()
{
//f(T(), T()); // it's fine for error here
typedef ns::TT TTT;
f(TTT(), T()); // why this issued an error?
f(ns::TT(), T()); // and this?
}
};
/* I also think it's OK to move ns here */
// namespace ns
// {
// typedef int TT;
// void f(int, int){};
//};
int main()
{
B<int> b;
b.g();
}
Please notice the second comment. Since "f" is a dependent name, its lookup should be delayed until the instantiation in the "main" function. And at that time, the compiler should perform an argument dependent name lookup at the scope of the main function. I think now it should discover the function in namespace ns, but it still issued a compile error:
1.cpp: In instantiation of 'void B<T>::g() [with T = int]':
1.cpp:30:6: required from here
1.cpp:23:15: error: 'f' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive] f(TTT(), T()); //why this issued an error?
^
1.cpp:23:15: note: declarations in dependent base 'A<int>' are not found by unqualified lookup
1.cpp:23:15: note: use 'this->f' instead
Could someone explain this to me? Thanks.