在专业化和重载之间切换

Switching between specialization and overloading

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

Call member_function

Derived member function

Call template_function

template function

Derived member function

正如预期的那样,这里没有调用 template_function 的特化,因为 derived 是 Base* 类型,而是调用了 member_function 的正确版本。

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

当 Derived class 的动态实例被声明为 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> 上添加两个您 enable_if 的模板 template_function,像这样

// 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