I recently came across an instance in which I realized that several classes I had written shared a lot of functionality. I realized I could generalize these classes into a common base with some template parameters. The problem is that these classes have about 20 different overloaded constructors, where most of the classes functionality is implemented. Using I came up with the solution illustrated here:
template <typename T>
class Base {
protected:
T member_;
public:
Base(int a) { /* ... */ }
Base(double a) { /* ... */ }
Base(char a) { /* ... */ }
Base(int a, double b, char c) { /* ... */ }
// etc...
};
class Derived1 : public Base<int> {
public:
template <typename... Args>
Derived1(Args... args) : Base(args...) { }
// other constructors specific to Derived1
};
class Derived2 : public Base<char> {
public:
template <typename... Args>
Derived2(Args... args) : Base(args...) { }
// other constructors specific to Derived2
};
I have several questions here:
- Is there any runtime performance hit associated with this? (After looking around, it seems like I should be using rvalue references and
std::forward
in the derived classes, right?) - From a code maintainability point of view, is this a good idea?
- What are some pitfalls of this approach? (e.g. similar examples elsewhere seem to be using the
explicit
keyword. Why?) - Is there a better, more standard, more safe, or more readable way to do this?