The idea is pretty simple: create a template class where the declaration of the (compile-time or run-time) parameters are extracted into a separate class.
The following two classes will be used to illustrate how to it.
template<int I0, int I1> struct CT {
int func() { return I0 + I1; }
};
struct RT {
int i0, i1;
RT(int i0, int i1) : i0(i0), i1(i1) { }
int func() { return i0 + i1; }
};First, let's extract the parameters into a separate class to isolate the state of the class from the behaviour.
template<int P0, int P1> struct CTParams {
static const int i0 = P0;
static const int i1 = P1;
};
template<typename PARAMS> struct CT {
int func() { return PARAMS::i0 + PARAMS::i1; }
};
struct RTParams {
int i0, i1;
RTParams(int i0, int i1) : i0(i0), i1(i1) { }
};
struct RT {
RTParams params;
RT(RTParams const& params) : params(params) { }
int func() { return params.i0 + params.i1; }
};Second, to make the body of CT::func and RT::func look the same we rewrite the code of CT into:
template<typename PARAMS>
struct CT {
PARAMS params;
int func() { return params.i0 + params.i1; }
};
template<typename PARAMS>
struct CTRT {
PARAMS params;
CTRT(PARAMS const& params = PARAMS()) : params(params) { }
int func() { return params.i0 + params.i1; }
};
void f() {
// Look here! Compile-time parameters!
CTRT<CTParams<10, 20> > ct;
ct.func();
// Look here! Run-time parameters! Omg!
CTRT<RTParams> rt(RTParams(10, 20));
rt.func();
}
Pretty straight-forward, right? There are a few downsides to this solution. The first is that there is a small overhead in memory usage of CTRT<CTParams<...>> compared to the original CT class. Luckily, this can easily be solved by using private inheritance (and the empty base class optimization).
Second, the implementation of CTRT<...> is much more complicated than the original RT class. However, this is a small price to pay compared to having multiple implementations.
Third, and most important, since CTRT is a template it must (usually) be implemented entirely in the header file, thus, increasing compilation times and potentially cause code bloat.
No comments:
Post a Comment