I have an abstract class
template <class T> struct A { /* virtual methods */ };
and several concrete derived classes with various constructors
// The constructor of B takes 1 input
template <class T>
struct B
: public A<T>
{
B() { /* default ctor */ }
B( T *input ) { /* initializer */ }
// .. implement virtual methods
}
// The constructor of C takes 2 inputs
template <class T>
struct C
: public A<T>
{
double some_member;
C() { /* default ctor */ }
C( T *input, double& value ) { /* initializer */ }
// .. implement virtual methods
}
I created a Factory that returns pointers to A
, and I am trying to use variadic templates to forward inputs to the constructor of the selected derived class. It is working fine, but I had to duplicate the code for the cases with/without constructor inputs, and I am looking for a way to prevent code duplication (see below).
template <class T>
struct A_Factory
{
typedef std::shared_ptr<A> out_type;
// Version without constructor inputs
static out_type create( id_type id )
{
out_type out;
switch (id)
{
// .. select the derived class
case Type_B:
out.reset( new B() );
break;
}
return out;
}
// Version with constructor inputs
template <class... Args>
static out_type create( id_type id, Args&&... args )
{
out_type out;
switch (id)
{
// .. select the derived class
case Type_B:
out.reset( new B( std::forward<Args>(args)... ) );
break;
}
return out;
}
};
Very sorry for the long question. Any suggestion to make this shorter appreciated.
create
function should be deleted, as it is useless. You still have a problem because code that constructsB
with 1 2 and 3 arguments will be generated, and only 2 arguments is valid. – Sclerotomyid_type
as a template argument, your only option is making all the constructors take the same arguments. – PurineT* maybe_new<T, Args...>
that returnsnullptr
if you cannot construct aT
fromArgs...
. Uses tag dispatching to dispatch to two implementations, onereturn nullptr;
and the otherreturn new T(std::forward<Args>(args)...);
– Sclerotomy