Proxy class template that have the same constructor signature of the represented class

Viewed 69

How to code a generic/templated proxy class P to have the same constructor signature of some represented classes C, and forward those arguments from P to C unaltered, without any runtime overhead?

(Because P is generic, C constructor may have any number and types of arguments, even none).

Example code:

class C {
public:
    C(int i, string s, bool b,... /* assorted number and types of arguments, maybe none */) {
        /* ... */
    }
    /* other methods */
};

template<typename T>
class P {
public:
    P(/* same arguments of T constructor */) {
        // get a T instance
        T t(/* forward arguments from P constructor, unaltered */);
        /* ... */
    }
    /* other methods */
};

Using P:

    P<C> p{/* arguments required by C */};
    p.some_p_method();
2 Answers

Could be done using private inheritance and the using keyword to "import" the constructors from C into P:

template<typename T>
class P : private T
{
public:
    using T::T;  // "Import" the T constructors
    // ...
};

Note that this scheme won't work if you need the proxy-class P to include some special initialization in its own construction.

You can use a template pack to create a constructor template that perfectly forwards the arguments to C. This way you can call each C constructor from the same P constructor template only depending on the arguments

#include <iostream>
#include <string>
#include <utility>
using std::cout;
using std::string;

class C {
public:
    C(int i, string s, bool b,... /* assorted number and types of arguments, maybe none */) {
        cout << i << '\n' << s << '\n' << b << '\n';
        /* ... */
    }
    /* other methods */
};

template<typename T>
class P {
public:
    template<typename ...Ts>
    P(Ts &&...ts) {
        // get a T instance
        T t(std::forward<Ts>(ts)...);
        /* ... */
    }
    void some_p_method() {}
    /* other methods */
};

int main() {
    P<C> p(1, string(), true);
    p.some_p_method();
}
Related