i. problem description:
class derived child of class base. can not modify class base. define constructors , assignement operators derived constructed both instances of:
base1derived1nnon-polymorphic , not related typesfoo1, ... ,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&); };