Consider
#include <iostream>
template <typename T>
void foo (T*) { std::cout << "foo (T*) called.\n"; }
template <typename T>
void foo (typename T::Node*) { std::cout << "foo (typename T::Node*) called.\n"; }
struct A {
struct Node { };
};
int main() {
A* a = new A;
foo(a);
A::Node* node = new A::Node;
foo(node);
}
Output:
foo (T*) called.
foo (T*) called.
How do I fix the code so that the second output gives foo (typename T::Node*) called.
?
CodePudding user response:
This is because when you call foo the type for T needs to be deduced by the compiler. Since both A and A::Node are valid for the first foo. And the second Foo is not more specific. It'll call the first version of foo (substituting T with A and A::Node). To force the compiler to replace T with A and then see T::Node* you can specify what the template argument should be.
foo<A>(node);
A quick way to see what the compiler is using for its types is by using the __PRETTY_FUNCTION__
macro. Which would output:
foo (T*) called. sig: void foo(T *) [T = A]
foo (T*) called. sig: void foo(T *) [T = A::Node]
for the original code and
foo (typename T::Node*) called. sig: void foo(typename T::Node *) [T = A]
for foo<A>(node);