如何使用模板化函数重载接受来自不同基类的派生类?

Vic*_*Liu 2 c++ inheritance templates

我希望能够定义

template <class TX>
void f(const TX &x){ ... }
template <class TY>
void f(const TY &x){ ... }
Run Code Online (Sandbox Code Playgroud)

其中TX必须从BaseX派生而TY必须从BaseY派生(我如何指定这种东西?),我希望能够将其称为

f(DerivedX<T>())
Run Code Online (Sandbox Code Playgroud)

最重要的是我可以避免指定模板参数.这是可能的,如果是这样,我将如何实现它?如果不可能,有没有办法让模板化函数只接受某些类型,但仍然可以隐式实例化它?我不能只是让f的重载接受基类,因为我需要派生类的类型.

Jam*_*lis 6

您可以使用is_base_ofBoost.TypeTraits像这样:

#include <boost/type_traits.hpp>
#include <boost/utility.hpp>

class BaseX { };
class BaseY { };

class DerivedX : public BaseX { };
class DerivedY : public BaseY { };

template <typename TX>
boost::enable_if<boost::is_base_of<BaseX, TX>, void>::type
f(const TX& x) 
{
}

int main(int argc, char** argv)
{
    DerivedX x;
    DerivedY y;

    f(x); // compiles
    f(y); // will cause a compilation error
}
Run Code Online (Sandbox Code Playgroud)

Boost.TypeTraits库只是标题,因此您无需链接任何内容.

  • 附录 - 如果条件为真,则enable_if的作用是只有一个`type`成员,因此如果你尝试使用`type`并且条件为false,则会导致编译错误.但是,由于称为SFINAE的原则(替换失败不是错误),这只是告诉编译器不要选择该版本的模板.如果你有另一个用于`BaseY`,编译器将无法创建两个模板中的一个,并被迫使用另一个.由于它将是唯一符合条件的模板,因此将被选中. (2认同)