【问题标题】:overload resolution of function templates函数模板的重载解析
【发布时间】:2016-10-23 18:33:47
【问题描述】:

问题是代码。看起来第二个功能比第一个更特别。为什么在下面的代码中调用更通用的?我怎样才能使其他功能被使用?

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 对象传递给函数。

【问题讨论】:

标签: c++ templates overloading overload-resolution


【解决方案1】:

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

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

如何才能使用其他功能?

您可以更改第二个函数模板的参数类型以避免隐式转换。您还可以将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


顺便说一句:我认为Base::print() 应该是一个虚函数。

【讨论】:

    【解决方案2】:

    简单的答案是:

    • template instantiation 在编译时完成:在编译时没有 可以取Derived&lt;int&gt;的函数,因此void func(T x)用于实例化该类函数的定义。

    implicit dynamic conversion 在运行时完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多