重载功能模板的解析

时间:2016-06-22 02:21:13

标签: c++ templates overloading overload-resolution

问题是代码。看起来第二个功能比第一个功能更特殊。为什么在下面的代码中调用更一般的?如何使用其他功能?

template <typename T>
class Base{
public:
    Base(){}
    void print() const {cout<<"Base class"<<endl;}
};

template <typename T>
class Derived :public Base<T>{
public:
    Derived() {}
    void print() const {cout<<"Derived class"<<endl;}
};

template <typename T>
void func(T x){    // <----- Why is function is called?
    x.print();
    cout<<"in func(T)"<<endl;
}

template <typename T>
void func(const Base<T>& x){
    x.print();
    cout<<"in func(Base<T>)"<<endl;
}

int main () {
    Base<int> b;
    Derived<int> d;
    func(d);
    return 0;
}

请注意,我将Derived对象传递给函数。

2 个答案:

答案 0 :(得分:0)

  

请注意,我将Derived对象传递给函数。

在这种情况下,对于第二个函数模板的参数,必须有一个隐式转换(从Derived<T>Base<T>)。而对于第一个功能模板,它是完全匹配并且是首选。

  

如何使用其他功能?

您可以更改第二个功能模板的参数类型以避免隐式转换。您还可以将std::enable_ifstd::is_base_of一起使用,使其仅适用于基类及其派生类。

template <typename T, template <typename> class D>
typename std::enable_if<std::is_base_of<Base<T>, D<T>>::value>::type
func(const D<T>& x){
    x.print();
    cout<<"in func(Base<T>)"<<endl;
}

Live Demo

BTW:我认为Base::print()应该是一个虚函数。

答案 1 :(得分:0)

简单的答案是:

  • template instantiation在编译时完成:在编译时没有 函数可以Derived<int>,因此void func(T x)用于实例化那种函数的定义。

implicit dynamic conversion在运行时完成。