如何在 CRTP 中的基类上使派生类模板化

How to make Derived class templated on Base class in CRTP

本文关键字:派生 基类 CRTP      更新时间:2023-10-16

假设,我有两个发动机类别(基于燃料类型,例如燃气或电力)

template<class Derived>
class ElectricEngine {};

template <typename Derived>
class GasEngine {};

现在假设我想做CarEnginePlaneEngine,每个基类都可以选择上述基类之一。我还需要做CRTP(静态多态性)。因此,执行此操作的直接方法如下:

class ElectricCarEngine : public ElectricEngine<ElectricCarEngine> {};
class GasCarEngine : public GasEngine<GasCarEngine> {};
class ElectricPlaneEngine : public ElectricEngine<ElectricPlaneEngine> {};
class GasPlaneEngine : public GasEngine<GasPlaneEngine> {};

上述方法有效,但它有很多冗余代码,因为我每种CarEngine类型的方法,即ElectricCarEngineGasCarEngine是相同的。ElectricPlaneEngineGasPlaneEngine的故事是一样的.

假设编译如下:

template <typename Base>
class CarEngineInterface : public Base<CarEngineInterface<Base> > {};

然后,我们可以重用这个类来通过简单的typedfs创建任何CarEngine类型。例如:

typedef CarEngineInterface<ElectricCarEngine> ElectricCarEngine;
typedef CarEngineInterface<GasCarEngine> ElectricCarEngine;

但是,由于循环依赖,这失败了。如何实现类似的效果?

有一些特质魔法可以解决这个问题吗?(就像那些用于从 CRTP 中的基类引用派生类类型定义一样)

我在 C++99 上,但我可以使用 Boost。我也是 c++ 模板的菜鸟。

如果我需要澄清任何事情,请告诉我。

创意链接:https://ideone.com/uMylVY

模板也可以接受模板作为参数,所以我认为这将起到:

template< class Engine > struct ElectricFueled { };
template< class Engine > struct GasFueled { };
template< template<class> class Fueled > struct CarEngine   : Fueled<CarEngine<Fueled> >   { };
template< template<class> class Fueled > struct PlaneEngine : Fueled<PlaneEngine<Fueled> > { };
CarEngine<ElectricFueled> myTeslaEngine;
PlaneEngine<GasFueled>    myMooneyEngine;

这可能是在结构语法方面分解它的最简单方法,但这只是一种方法。 尝试很多变化,看看什么会让以后的生活变得最轻松。