The problem with mixins is... construction.
class Base1 { public: Base1(Dummy volatile&, int); };
class Base2 { public: Base2(Special const&, Special const&); };
And now, my super mixin:
template <typename T>
struct Mixin: T {};
Do you notice the issue here ? How the hell am I supposed to pass the arguments to the constructor of the base class ? What kind of constructor should Mixin
propose ?
It's a hard problem, and it has not been solved until C++11 which enhanced the language to get perfect forwarding.
// std::foward is in <utility>
template <typename T>
struct Mixin: T {
template <typename... Args>
explicit Mixin(Args&&... args): T(std::forward<Args>(args...)) {}
};
Note: double checks are welcome
So now we can really use mixins... and just have to change people habits :)
Of course, whether we actually want to is a totally different subject.
One of the issues with mixins (that the poor article you reference happily skip over) is the dependency isolation you completely lose... and the fact that users of LoggingTask
are then bound to write template methods. In very large code bases, more attention is given to dependencies than to performance, because dependencies burn human cycles while performance only burn CPU cycles... and those are usually cheaper.