有没有转发方法的通用方法? [英] Is there a generic way to forward constructor arguments?
问题描述
我下面有一个有效的 Cloneable / CloneableImpl
类对。只要我有从子级到父级的默认构造函数,它就可以工作。
I have a working Cloneable/CloneableImpl
class pair below. It does its job as long as I have default constructors from child to parent.
假设将Animal的构造函数修改为 Animal(std :: string const& ; name)
,它需要从子类构造函数中传递名称。
Suppose Animal's constructor is modified to Animal( std::string const& name )
, which needs the name to be passed up from the children class constructors.
如何在保持 Cloneable / CloneableImpl
通用性的同时将这一要求纳入结构中?
How can I incorporate this requirement into the structure while keeping Cloneable/CloneableImpl
generic?
换句话说,我需要能够将所有构造函数参数从Lion,Tiger转发到Animal。有没有一种方法可以在C ++ 11中以通用方式执行此操作?
如果不可能,如何将这些模板进行重组以保持通用性
If it's not possible, how can these templates be restructured to remain generic while allowing for the constructor requirement?
代码
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" );
}
推荐答案
跟随@ Cheersandhth.-Alf和@R。 Martinho Fernandes在对OP的评论中的建议,以调查完美转发。我研究了一下,并提出了这个建议,似乎可行。
Following @Cheersandhth.-Alf and @R. Martinho Fernandes' suggestions in the Comments to the OP to look into perfect forwarding. I researched a bit and came up with this, which seems to work.
谢谢大家!
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;
}
这篇关于有没有转发方法的通用方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!