I am creating a class library with many different options for possible customizations. For example, you can design your class so that it can perform FeatureX(), or you can design your class so that it can perform FeatureY().
Under normal circumstances, you would simply create an interface IFeatureX with a pure virtual method called FeatureX, and another interface IFeatureY with a pure virtual method called FeatureY. If a class has both FeatureX and FeatureY, it can inherit from both, no problem.
My problem is, what if a function/method requires an object that can perform both FeatureX() and FeatureY()? How do I express a type, in C++ preferably, but an answer in Java could help as well, to ensure that both FeatureX and FeatureY are available?
Do I create another interface IFeatureXY that inherits from IFeatureX and IFeatureY? Okay… if there are only two features I could get away with this. But if there are say… 10 features, the number of possible interfaces becomes massive.
Is there a simple way to do this? I tried solving the problem using C++ templates and delegation but didn’t get too far. I’m hoping there is a simple solution to this, and there probably is one that I just overlooked.
I appreciate any help and advice you guys have.
Thanks.
If you’re not afraid of using templates, you can make your function a template and use SFINAE to check for the two interfaces:
This will create a method for every type that extends both feature interfaces (note that the SFINAE trick is not needed for it to work; an unconstrained template would work, but just fail to compile when you pass a type that doesn’t meet the requirements).
Another possibility is to create an interface IFeatureXY extending both, and use this in the function parameters; this has the drawback that types that do implement both interfaces, but not this joint interface would not be usable with this method.
Also, you can pass two arguments to the function, one per interface, and require they are pointers to the same object; this is fragile, but could be hardened by making some template class to hold the two pointers – eg.
product_type<IFeatureX*, IFeatureY*>, which would be initialized by the single object in question and which would hold the two types.In Java, you could probably do the same thing with bounded type variables (if they allow multiple bounds; I’m not sure now).