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.
CodePudding user response:
ADL is argument dependent lookup. A function name is looked for in the associated namespaces of its arguments. int
has no associated namespaces, so no ADL occurs. Even if it did occur, it would only find free functions, so your method would not be found.