在专业化和过载之间切换

Switching between specialization and overloading

本文关键字:之间 专业化      更新时间:2023-10-16

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

调用member_function

派生成员函数

调用template_function

模板函数

派生成员函数

正如预期的那样,这里没有调用template_function的专门化,因为派生的类型是Base*,但调用了member_function正确的版本。

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

是否有一种方法可以确保当派生类的动态实例声明为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);
}

您可以在std::base_of<T, Derived>上添加两个模板template_functionenable_if,就像这个

// 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);
}

实例

或者,更简单的是,您可以简单地添加一个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();
}

实时示例