函数重载涉及模板?

时间:2014-05-23 14:53:17

标签: c++ templates overloading

我有几个重载函数:

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?

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不能 叫,所以第二个将被调用。