我有几个重载函数:
class A {};
class B : public A {};
template<class T> void f(T a) {} // function 1
void f(A* p) {} // function 2
当我打电话
B* b;
f(b); // the function 1 is called other than the 2
我希望调用版本2。为什么不以及如何调用版本2?
答案 0 :(得分:3)
您使用子类指针调用了您的函数。模板完全匹配,而调用函数1则需要转换为基指针。因此,模板调用是更好的匹配。
您可以向基类显式static_cast
以强制调用基指针版本,或者我相信您可以使用enable_if
之类的内容来禁用{{1}的子项的模板}。
答案 1 :(得分:2)
编译器选择它可以看到的最佳重载。类型
扣除将您的模板实例化为f(B*)
,以及那些
显然比f(A*)
更好的过载。通常的解决方案
这就像:
void f( A* p )
{
}
template <typename T>
void doF( T a, A const* )
{
f( static_cast<A*>( a ) );
}
template <typename T>
void doF( T a... )
{
// your current template implementation
}
template <typename T>
void f( T a )
{
doF<T>( a, 42 );
}
template <typename T>
void f( T* a )
{
doF<T*>( a, static_cast<T*>( 0 ) );
}
上面的工作原因是因为非指针类型是唯一的功能
可以调用的是上面的第一个模板,它将结束
在你的模板实现中。对于指针类型,最后一个
模板更专业,因此将是更好的匹配
(除非指针是A*
,在这种情况下,非模板
函数将被调用);它将传递一个类型的空指针
T*
到doF
。如果T*
隐式转换为A *,则为第一个
doF
是更好的匹配;否则,第一个doF
不能
叫,所以第二个将被调用。