I'm testing the following code:
#include <iostream> template<typename T> class A { public: void koo(T) { std::cout << "Hello world!"; } }; template <typename T> class B : public A<T> { public: void pun(T i) { koo(i); } }; int main() { B<int> boo; boo.pun(5); } with compilation info as:
main.cpp:12:24: error: ‘koo’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive] 12 | void pun(T i) { koo(i); } | ~~~^~~ main.cpp:12:24: note: declarations in dependent base ‘A’ are not found by unqualified lookup main.cpp:12:24: note: use ‘this->koo’ instead I know I can avoid this error with this->koo(i) or A<T>::koo(i), but I want to understand why this compilation error happens.
I think koo in pun definition is a dependent name, according to dependent name / lookup rules "the lookup of a dependent name used in a template is postponed until the template arguments are known". In the main function, B<int> boo; sets the template parameter as int. Then why ADL doesn't work for the function expression koo(i) ? ————————————————————————————————
And let's put ADL aside momentarily. If I change void pun(T i) { koo(i); } to void pun(T i) { goo(i); }, now the new compilation info is:
main.cpp:12:24: error: ‘goo’ was not declared in this scope; did you mean ‘koo’? 12 | void pun(T i) { goo(i); } | ~~~^~~ | koo Why compilation info for the two cases are different? The new error doesn't mention "argument-dependent lookup" at all.
koointoB’s space withusing A<T>::koo;anywhere you find convenient.