Let's say I have an interface and a class implementing it, like this:
class IPrinter
{
public:
virtual void print(int i, int base = 10) = 0;
virtual void print(char c) = 0;
virtual void print(char *s) = 0;
virtual void print(float f) = 0;
virtual void print(double d) = 0;
virtual ~IPrinter() = default;
private:
...
}
class Printer : public IPrinter
{
public:
void print(int i, int base = 10) override {...}
void print(char c) override {...}
void print(char *s) override {...}
void print(float f) override {...}
void print(double d) override {...}
private:
...
}
And then I decide to add a simple decorator class, like this:
class SwitchablePrinter : public IPrinter
{
private:
IPrinter& _printer;
bool _enabled;
...
public:
SwitchablePrinter(IPrinter& p) :
_printer(p),
_enabled(true)
{
}
void print_enable(bool on) { _enabled = on; }
void print(int i, int base = 10) override
{
if (_enabled)
_printer.print(i, base);
}
void print(char c) override
{
if (_enabled)
_printer.print(c);
}
void print(char *s) override
{
if (_enabled)
_printer.print(s);
}
void print(float f) override
{
if (_enabled)
_printer.print(f);
}
void print(double d) override
{
if (_enabled)
_printer.print(d);
}
}
Now, all this is pretty simple and straightforward. The problem is that there is a lot of code duplication in the SwitchablePrinter implementation. I was wondering, that if there was a way to write a generic method 'print' for all overloaded methods in the base class, like this:
(pseudo-code)
void print({any args})
{
if (_enabled)
_printer.print({any args});
}
I think there may be a solution using templates, but I am not very experienced with using them and need advice.
Although there is no mechanism to override multiple member functions at once, you can simplify your task and reduce code duplication by providing a private variadic member function template that forwards the call to the proper overload of the wrapped _printer
, like this:
private:
template <class ... T>
void print_impl(T ... vals) {
if (_enabled)
_printer.print(vals...);
else
cout << "disabled" << endl;
}
public:
void print(int i, int r) override {
print_impl(i, r);
}
void print(float f) override {
print_impl(f);
}
void print(double d) override {
print_impl(d);
}
void print(char* s) override {
print_impl(s);
}
void print(char c) override {
print_impl(c);
}
Demo.
This is only a slight improvement on the original, because the forwarding logic of print_impl
is so simple. When the logic becomes more complex, payoff from sharing the code increases.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With