Lets say, I have two Engine classes (based on fuel type eg 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 ie 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.