在专业化和重载之间切换

时间:2016-03-29 12:13:18

标签: c++ templates polymorphism overloading

从下面的代码中,我得到以下输出:

  

调用member_function

     

派生成员函数

     

调用template_function

     

模板功能

     

派生成员函数

正如所料,此处未调用template_function的特化,因为derived类型为Base *,但调用了member_function的正确版本。

但是,有时,在模板函数中调用非成员函数可能很有用。

当Derived类的动态实例被声明为Base *类型时,是否存在确保调用模板函数的专用版本的方法?

谢谢!

#include <iostream>

// Base and Derived classes

class Base
{
    public:
        virtual void member_function() const
        { std::cout << "Base member function" << std::endl; };
};

class Derived : public Base
{
    public:
        virtual void member_function() const
        { std::cout << "Derived member function" << std::endl;};
};


// Functions

template<typename T>
void template_function(T const & arg)
{
    std::cout << "template function" << std::endl;
    arg.member_function();
}

template<>
void template_function(Derived const & arg)
{
    std::cout << "Specialized function" << std::endl;
    arg.member_function();
}


// Main

int main ()
{
    Base * derived = new Derived();;

    std::cout << "Call member_function" << std::endl;
    derived->member_function();

    std::cout << std::endl;

    std::cout << "Call template_function" << std::endl;
    template_function(*derived);

}

1 个答案:

答案 0 :(得分:1)

您可以在template_function添加enable_if的两个模板std::base_of<T, Derived>,就像这样

// Functions
template<typename T, std::enable_if_t<not std::is_base_of<T, Derived>::value>* = nullptr>
void template_function(T const & arg)
{
    std::cout << "template function" << std::endl;
    arg.member_function();
}

template<typename T, std::enable_if_t<std::is_base_of<T, Derived>::value>* = nullptr>
void template_function(T const & arg)
{
    std::cout << "Specialized function" << std::endl;
    arg.member_function();
}


// Main

int main ()
{
    Base const * base = new Base();
    Base const * derived = new Derived();

    std::cout << "Call member_function" << std::endl;
    base->member_function();
    derived->member_function();

    std::cout << std::endl;

    std::cout << "Call template_function" << std::endl;
    template_function(*base);
    template_function(*derived);

}

Live Example

或者,更简单一点,您只需添加template_function(Base const&)重载

即可
// Functions
template<typename T>
void template_function(T const & arg)
{
    std::cout << "template function" << std::endl;
    arg.member_function();
}

void template_function(Base const & arg)
{
    std::cout << "Specialized function" << std::endl;
    arg.member_function();
}

Live Example