Is there a general way to redirect constructor arguments?

I have a working Cloneable/CloneableImpl pair below. It does its job as long as I have default constructors from child to parent.

Suppose that the Animal constructor is modified to Animal( std::string const& name ) , which requires a name that must be passed from the constructors of the children classes.

How can I include this requirement in a structure while retaining the Cloneable/CloneableImpl generic?

In other words, I need to be able to forward all constructor arguments from Lion, Tiger to Animal. Is there a way to do this in C ++ 11 in a generic way?

If this is not possible, how can these templates be restructured to remain generally accepted, given the requirement of the constructor?

the code

 template<typename P> struct Cloneable { virtual P* clone() const = 0; }; template<typename T,typename P> struct CloneableImpl : public P { virtual P* clone() const { return new T( dynamic_cast<T const&>(*this)); } }; // ---------------------------------------------------------------------------- struct Animal : public Cloneable<Animal> { }; struct Lion : public CloneableImpl<Lion,Animal> { }; struct Tiger : public CloneableImpl<Tiger,Animal> { }; int main( int argv, char* argc[] ) { Animal* x = new Lion; Animal* y = x->clone(); // we want to do this without hard-coding in template classes // Animal* z = new Lion( "Samba" ); } 
+8
c ++ constructor clone c ++ 11 templates
source share
1 answer

Following @ Cheersandhth.-Alf and @R. Martinho Fernandes offers in the OP comments to learn about the perfect redirect . I studied a little and came up with this that seems to work.

Thanks guys!

CODE

 #include <string> #include <iostream> template<typename P> struct Cloneable { virtual P* clone() const = 0; }; template<typename T,typename P> struct CloneableImpl : public P { template<typename... Args> CloneableImpl( Args&&... args ) : P(std::forward<Args>(args)...) { } virtual P* clone() const { return new T( dynamic_cast<T const&>(*this)); } }; // ---------------------------------------------------------------------------- struct Animal : public Cloneable<Animal> { Animal( std::string const& name ) : m_name( name ) { } std::string m_name; }; struct Lion : public CloneableImpl<Lion,Animal> { template<typename... Args> Lion( Args&&... args ) : CloneableImpl<Lion,Animal>(std::forward<Args>(args)...) { } }; struct Tiger : public CloneableImpl<Tiger,Animal> { }; int main( int argv, char* argc[] ) { Animal* x = new Lion( "Samba" ); Animal* y = x->clone(); std::cerr << y->m_name << std::endl; } 
+8
source share

All Articles