Imagine I have M methods that I want to time, along with N timing methods (let's call them clock implementations)1. The exact details aren't too important here, but I'm mentioning it so I can give a concrete example.
Now let's say I have a templatized timing method like so:
typedef void (bench_f)(uint64_t);
template <bench_f METHOD, typename CLOCK>
uint64_t time_method(size_t loop_count) {
auto t0 = CLOCK::now();
METHOD(loop_count);
auto t1 = CLOCK::now();
return t1 - t0;
}
Basically it brackets the call to METHOD with calls to CLOCK::now() and returns the difference. Note also that METHOD is not passed as a function pointer, but rather only as a template argument - so you get unique instantiations for each method, rather than one and then an indirect call through a pointer.
This works well for my case because both of the clock calls and the method under test are direct static calls (i.e., something like call <function address> at the assembly level).
Now I have N methods I want to test (perhaps 50) along with M clock methods (perhaps 5). I want to actually instantiate, at compile time, all M * N methods, so that I can call all the test methods with a specific clock implementation.
Now the "standard" way to do this would just to pass a function pointer (or class implementing a virtual function) for both the method under test and the clock implementation, at which point I'd only need a single time_method method and can create whatever combination I want at runtime. In this particular case, the performance impacts of the indirect calls are too much, so I want template instantiation and I am willing to pay the resulting binary bloat (e.g., M * N = 250 instantiated combinations with my numbers).
At runtime I want to get a list of N method combined with a particular clock, for example.
I am fine explicitly listing all N method and all M clocks, but I don't want to write out the M * N instantiations (DRY and all that).
1 I'm using the word clock pretty loosely here - some of the "clocks" may in fact measure aspects unrelated to time, such as heap memory use, or some application specific metric.