kfm*_*e04 9 c++ templates constructor clone c++11
我Cloneable/CloneableImpl下面有一个工人阶级对.只要我有从子节点到父节点的默认构造函数,它就能完成它的工作.
假设Animal的构造函数被修改为Animal( std::string const& name ),需要从子类构造函数传递名称.
如何在保持Cloneable/CloneableImpl通用的同时将此要求纳入结构中?
换句话说,我需要能够将Lion,Tiger的所有构造函数参数转发给Animal.有没有办法以通用方式在C++ 11中执行此操作?
如果不可能,那么在允许构造函数要求的同时,如何重构这些模板以保持通用?
码
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" );
}
Run Code Online (Sandbox Code Playgroud)
kfm*_*e04 10
关注@ Cheersandhth.-Alf和@R.Martinho Fernandes在对OP的评论中提出建议,以寻求完美转发.我研究了一下,想出了这个,这似乎有效.
多谢你们!
码
#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;
}
Run Code Online (Sandbox Code Playgroud)