I'm working on a monitoring tool and I'm focusing on having low runtime overhead and a simple API. For low-overhead runtime on/off switching I chose to use the state pattern, and to simplify the usage I was going for template parameter packs.
And now for the first time I'm fighting on the line separating compile-time and run-time, and of course can't get a virtual template function to work.
I'm looking for a workaround or an equivalent solution considering the following constraints :
- Lowest runtime-cost of "disabled" state
- Flexible API
- Pre C++17 compliance
And if it's not possible, that's fine too...
Code sample :
static struct /*Disabled*/ State
{
template <typename... Args>
/*virtual*/ void operator()(const char * category, Args&&... args) { /*noop*/ }
}
disabled;
static struct Enabled : State
{
template <typename... Args>
/*virtual*/ void operator()(const char * category, Args&&... args) { /*processing category and args*/ }
}
enabled;
struct Monitor
{
static State* state;
template <typename... Args>
static void write(const char * category, Args&&... args)
{
state->operator()(category, std::forward<Args>(args)...);
}
};
State* Monitor::state = &enabled;
int main()
{
Monitor::write("BulletCount", 42);
Monitor::write("Spell", "EnergyShield", true);
}
The code above compiles, but I can never reach the Enabled state without virtual inheritance. Removing the template and having a ton of overloads would do it, but if it can be avoided it could become quite an elegant solution.