I have 6 types of datastructure<T>
.
All of them contains cover 10-20 common functions (purple) e.g. addFirst()
.
However, some datastructures has its own 0-5 unique functions (pink).
For example, only MyArray<T>
has function addManual(T,int)
.
In rare cases, some different types of datastructure support a few same special function.
(The real-case table is ~ 10x more complex.)
Here is a short snippet :-
class Vector3D{};
template<class T>class MyArray{
public: void addFirst(T t){/* some code */}
/* other add / remove / query function */
public: void addManual(T t,int internalIndex){/* some code */}
};
template<class T>class MyGrid3D{
public: void addFirst(T t){/*some code */}
/* other add / remove / query function */
public: void addSpecial(T t,Vector3D gridAddress){/* some code*/}
};
It works good so far.
Now, I want to make it usage easier by providing interface Adapter<MyX,T,I>
.
The user of my library can identify the internal stored type T
and the interface I
separately.
Whenever a parameter of function (purple/pink) has type I
, I will convert it to T
and internally manipulate it as if it has type T
.
Here is my prototype :-
template<template<class> class MyX,class T,class I>class Adapter{
private: T convert(I i){/* some logic */ return T();}
MyX<T> database;
public: void addFirst(I i){
database.addFirst(convert(i));
}
};
int main() {
Adapter<MyArray,int,std::string> adapter;
adapter.addFirst(std::string("5.0f"));
std::cout<<"compiled OK";
return 0;
}
It works good (coliru demo), but it doesn't cover special function (purple) e.g. addManual()
or addSpecial()
.
Question
What is a design pattern / C++ magic to make Adapter
support those functions?
Here are my three poor solutions :-
Create many adapter class for each type of datastructure, e.g.
AdapterMyArray<T,I>
andAdapterMyGrid3D<T,I>
.Improve the first solution by inheritance e.g.
AdapterMyArray<T,I>
andAdapterMyGrid3D<T,I>
derived fromAdapterBase<T,I>
.Check type of
MyX
and usestd::enable_if
to enable instantiate of those special functions.
I feel that all my solutions are somehow too manual and it will cause some maintainability issue.
Edit: Yakk's solution is good, but I still doubt if there are even better solution.