在专业化和重载之间切换
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);
}
或者,您可以简单地添加一个 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();
}
从下面的代码中,我得到以下输出:
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);
}
或者,您可以简单地添加一个 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();
}