使用类模板扩展抽象基类

时间:2016-03-31 17:31:10

标签: c++

当我还希望有条件地编译纯虚函数的覆盖时,如何使用扩展模板扩展抽象基类?

示例:给定基类

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;

不会编译,因为派生类仍然是抽象的。我使用模板是因为我希望编译器只选择一个要编译的成员函数。

感谢。

2 个答案:

答案 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();
}

但是,我认为混合动态多态(虚拟)和静态多态(模板)是一种糟糕的设计(可能有豁免)。