在重用基本模板实现中替代虚拟继承

Alternative to virtual inheritance in re-using base template implementation

在我正在处理的一个项目中,我们使用了一种模式,其中我们有纯抽象 类 定义接口,以及可以使用不同模板参数实例化的模板实现,这些模板用于许多东西,包括依赖注入。类似于:

struct Base {
  virtual int getVal() = 0;
};

template <typename DI>
struct BaseImpl : public Base {
  int getVal() override { return DI::k_Val; }
};

我想第零个问题是这是否是一个 known/common/formal 模式,如果是,它的名字是什么?

一个经常出现的需求是扩展 Base 接口,比如 Inherited。任何 Inherited 对象仍应具有多态功能,如 Base,但也可作为 Inherited,它可以定义其他方法。类似于:

struct Inherited : public Base {
  virtual int getOtherVal() = 0;
};

问题在于在 InheritedImpl<> 中重新使用 BaseImpl<> 的实现。因为 InheritedImpl<> 需要继承 InheritedBaseImpl<> 我们 运行 到 "dreaded dimond" problem, so we have to use virtual inheritance. See working example in godbolt.

struct Base {
  virtual int getVal() = 0;
};

template <typename DI>
struct BaseImpl : public virtual Base {
  int getVal() override { return DI::k_Val; }
};

struct Inherited : public virtual Base {
  virtual int getOtherVal() = 0;
};

template <typename DI>
struct InheritedImpl : public Inherited, public BaseImpl<DI> {
  int getOtherVal() override { return DI::k_OtherVal; }
};

void useBase(Base& base) {
    std::cout << "getVal: " << base.getVal() << std::endl;
}

void useInherited(Inherited& inherited) {
    std::cout << "getOtherVal: " << inherited.getOtherVal() << std::endl;
}

struct DI {
  static constexpr int k_Val = 1;
  static constexpr int k_OtherVal = 2;
};

int main() {
  auto base = std::make_unique<BaseImpl<DI>>();
  auto inherited = std::make_unique<InheritedImpl<DI>>();

  useBase(*base);
  useBase(*inherited);
  useInherited(*inherited);
}
getVal: 1
getVal: 1
getOtherVal: 2

因为 issues with virtual inheritance 我想尽可能避免在这里使用它。在这种情况下还有其他选择吗?这可能是代码味道吗?有什么架构建议吗?

基本模式是:

struct Base{
  virtual int count()const=0;
};
template<class X, class B=Base>
struct CountImpl:B{
   int count()const final{ return X::count; }
};

现在我们可以CountImpl<Foo, Extended>对继承进行变基。

可以完成更高级的东西,包括插件方面等。在更简单的情况下,这是不值得的,应该避免确实需要它的复杂情况。