Saturday, 7 September 2013

Faking virtual variadic template function

Faking virtual variadic template function

pI am trying to modularise logging code from a large codebase because the
live logging framework (Apache) makes our code tightly coupled to it and
this makes it very hard to write unit tests. I am stuck by the fact I
cannot have virtual templated functions. My current approach can be
summarised by the following:/p precode// Context.h struct Logger {
template lt;typename... Argsgt; void operator()(const char* aFormat,
Argsamp;amp;... aArgs) { // This function would ideally be virtual. // Is
there a funky way to get this function to call // a derived class'
implementation instead. } }; class Context { public: Context(const
Loggeramp; aLogger) : iLogger(aLogger) { } template lt;typename... Argsgt;
void DEBUG(const char* aFormat, Argsamp;amp;... aArgs) { iLogger(aFormat,
aArgs...); } private: const Loggeramp; iLogger; }; // MyType.h #include
Context.h class MyType { public: MyType(Contextamp; aCtx) : iCtx(aCtx) {
DEBUG(gt; ctor); DEBUG(lt; ctor. this=%p, this); } private: template
lt;typename... Argsgt; void DEBUG(const char* aFormat, Argsamp;amp;...
aArgs) { iCtx(aFormat, aArgs...); } Contextamp; iCtx; }; // main.cpp
#include MyType.h template lt;typename... Argsgt; static void
StdErrLog(const char* aFormat, Argsamp;amp;... aArgs) { fprintf(stderr,
aFormat, aArgs...); } struct StdErrLogger : public Logger { // This
function never gets called because it's not virtual. template
lt;typename... Argsgt; void operator(const char* aFormat, Argsamp;amp;...
aArgs) { StdErrLog(aFormat, aArgs...); } } int main(...) { StdErrLogger
logger; // For unit tests this could be 'EmptyLogger' for example. Context
ctx(logger); MyType t(ctx); } /code/pre pSo close yet so far. Is there
anything I can do to make this work without template-ising the
codeContext/code class? The code base isn't templated at all and I'm very
reluctant to go down this route as it'll be a lot of tedious work./p pIf
it can be done by keeping the templates down to function-level scope I'd
be very happy to see solutions. Function pointers are acceptable too, but
I'm not sure about the feasibility of getting the address of variadic
templated functions./p pThanks/p

No comments:

Post a Comment