考虑
#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.
如何修复代码,使第二个输出给出foo (typename T::Node*) called.
?
这是因为当您调用foo时,T的类型需要由编译器推导。由于A和A::Node对于第一个foo都是有效的。第二个Foo并没有更具体。它将调用foo的第一个版本(用A和A::Node代替T(。要强制编译器将T替换为A,然后看到T::Node*,可以指定模板参数应该是什么。
foo<A>(node);
查看编译器对其类型使用什么的一种快速方法是使用__PRETTY_FUNCTION__
宏。哪个会输出:
foo (T*) called. sig: void foo(T *) [T = A]
foo (T*) called. sig: void foo(T *) [T = A::Node]
对于原始代码和
foo (typename T::Node*) called. sig: void foo(typename T::Node *) [T = A]
对于foo<A>(node);
请参阅https://godbolt.org/z/4xb45svYW