当我还希望有条件地编译纯虚函数的覆盖时,如何使用扩展模板扩展抽象基类?
示例:给定基类
class AbstractBase {
public:
virtual void func() = 0;
};
我想用
之类的东西来扩展enum class Opts{FOO, BAR};
template<Opts opt>
class Derived : public AbstractBase {
public:
template<Opts op = opt>
typename std::enable_if<op == Opts::FOO, void>::type func() {
std::cout << "Foo" << "\n";
}
template<Opts op = opt>
typename std::enable_if<op == Opts::BAR, void>::type func() {
std::cout << "BAR" << "\n";
}
};
我的想法是当其中一个func在扩展类中编译时,一切都很好。但是,我无法让它发挥作用。
Derived<Opts::FOO> obj;
不会编译,因为派生类仍然是抽象的。我使用模板是因为我希望编译器只选择一个要编译的成员函数。
感谢。
答案 0 :(得分:1)
只需为每个待处理特别枚举值专门化类模板,例如
enum class Opts{foo, bar};
template<Opts opt>
class Derived;
template<>
class Derived<Opts::foo>
: public AbstractBase
{
public:
void func() override
{
std::cout << "Foo" << "\n";
}
};
template<>
class Derived<Opts::bar>
: public AbstractBase
{
public:
void func() override
{
std::cout << "bar" << "\n";
}
};
如果你想要一些不在AbstractBase
中的常见常见内容,你可以继承它,或者在最派生的类中通过CRTP添加它。
免责声明:关闭袖口代码,不编译。
答案 1 :(得分:1)
您可以专门使用该功能:
#include <iostream>
class AbstractBase
{
public:
// You should have a virtual destructor:
virtual ~AbstractBase() {}
virtual void func() = 0;
};
enum class Opts
{
FOO, BAR
};
template<Opts opt>
class Derived: public AbstractBase
{
public:
void func() override;
};
template<>
void Derived<Opts::FOO>::func()
{
std::cout << "Foo" << "\n";
}
template<>
void Derived<Opts::BAR>::func()
{
std::cout << "BAR" << "\n";
}
int main()
{
Derived<Opts::FOO> foo;
AbstractBase& bfoo = foo;
bfoo.func();
Derived<Opts::BAR> bar;
AbstractBase& bbar = bar;
bbar.func();
}
但是,我认为混合动态多态(虚拟)和静态多态(模板)是一种糟糕的设计(可能有豁免)。