#include <iostream>
void foo()
{
std::cout << "global foo()" << std::endl;
}
struct A {
void foo()
{
std::cout << "A::foo()" << std::endl;
}
};
struct B : public A {
void call()
{
foo();
}
};
int main(int argc, char **argv )
{
B b;
b.call();
return 0;
}
This gives expected result:
A::foo()
However after changing two lines (class B to template):
#include <iostream>
void foo()
{
std::cout << "global foo()" << std::endl;
}
struct A {
void foo()
{
std::cout << "A::foo()" << std::endl;
}
};
template <typename T> // change here
struct B : public T {
void call()
{
foo();
}
};
int main(int argc, char **argv )
{
B<A> b; // and here
b.call();
return 0;
}
I get unexpected result:
global foo()
And using this-> is not an option as I am trying to create a “fallback” mechanism.
What you get is an expected result. This is called “Two-phase name lookup” in the C++ standard.
Names inside templates are divided into two types:
Dependent – names that depend on the template parameters but aren’t declared within the template.
Non-dependent – names that don’t depend on the template parameters, plus the name of the template itself and names declared within it.
When the compiler tries to resolve some name in the code, it first decides whether the name is dependent or not, and the resolution process stems from this distinction. While non-dependent names are resolved “normally” – when the template is defined, the resolution for dependent names happens at the point of the template’s instantiation.
foo();inB::callin your example is a non-dependent name, so it is resolved to globalfoo()at the point of template definition.