문제

Lets say, I have two Engine classes (based on fuel type e.g Gas or Electric)

template<class Derived>
class ElectricEngine {};

and

template <typename Derived>
class GasEngine {};

Now say I want to make CarEngine and PlaneEngine, each of which can choose one of the above base classes. Also I need to do CRTP (static polymorphism). So a straight forward way to do this are as following:

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

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

The above works, but its lot of redundant code, since my methods of each CarEngine types i.e ElectricCarEngine and GasCarEngine are same. Its the same story for ElectricPlaneEngine and GasPlaneEngine.

Assuming something like below compiles :

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

We can then reuse this class to create any CarEngine Types by simple typedfs. For example:

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

However this fails because of the cyclic dependency. How can I achieve a similar effect?

Is there some traits magic to solve this? (Like the ones used to refer Derived class typedefs from base classes in CRTP)

I am on C++99 but I can use Boost. Also I am a noob in c++ templates.

Let me know if I need to clarify anything.

Ideaone link: https://ideone.com/uMylVY

도움이 되었습니까?

해결책

Templates can also accept templates as arguments, so I think this will serve:

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;

This might be the simplest way to break it out in terms of structural syntax, but it's only one way to do it. Try lots of variations to see what's going to make life easiest later on.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top