Home > Net >  Overloading with template nested type
Overloading with template nested type

Time:02-23

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);

See https://godbolt.org/z/4xb45svYW

  • Related