c++ - Class with both template and non-template constructor -


i. problem description:

class derived child of class base. can not modify class base. define constructors , assignement operators derived constructed both instances of:

  • base1

  • derived1

  • n non-polymorphic , not related types foo1, ... , foon2.

1 construction both base , derived done using base copy constructor.

2 construction of foo1, ... , foon done generic algorithm.

ii. possible solutions:

1. brute force:

n+1 separate constructors + n+1 separate assignment operators. absolutely not elegant. tons of useless code: n+1 methods declarations in header + n+1 methods implementations in source. power of templates not used.

2. template constructor type restriction

declare , define regular copy-constructor

derived::derived ( const base& object_reference ) { ... } 

declare template constructor:

template<typename type> derived::derived ( const type& object_reference ); 

implement each of foo0, ... , foon

template<> derived::derived<foo0> ( const foo0& object_reference ) { ... }  ...  template<> derived::derived<foo9> ( const foo9& object_reference ) { ... } 

as result header contain 2 constructors , 2 assignment operators. have implement n+1 methods in source. believe there better solution anyway.

iii. not work:

1. separating `base` , `derived` others using `dynamic_cast`

template<typename type> derived::derived ( const type& object_reference ) {      //  line not compile since `foo0`, ... , `foon` non-polymorthic     base* base_ptr = dynamic_cast <base*> (&object_reference);      if ( base_ptr != nullptr )     {          //  construct `base`         return;      }      //  construct `foo0`, ... , `foon`  } 

2. separating `base` , `derived` others using `typeid`

template<typename type> derived::derived ( const type& object_reference ) {      if     (         typeid(typename) == typeid(foo0)             ||             ...             ||         typeid(typename) == typeid(foon)     }     {          //  construct `foo0`, ... , `foon`         return;      }      else     {          //  construct `base`          //  here should call `base` members `foo0`, ... , `foon` don't have         //  following line not compile         //  object_reference.some_method();         //  , need cast "&object_reference" "base*" not possible         //  because `foo0`, ... , `foon` not polimorthic      }  } 

iv. question:

is there efficient way, not described in section ii, solve problem?

you don't need use typeid here:

2. separating `base` , `derived` others using `typeid` 

just make 2 non-template ctors , 1 template ctor foo classes:

class derived : public base {  public:   derived(const derived&);   derived(const base&);    template<class foo>   derived(const foo&); };