【发布时间】:2012-12-16 20:00:36
【问题描述】:
我在下面有一个有效的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" );
}
【问题讨论】:
-
听起来像继承的构造函数。不过,还没有多少编译器实现它们。用完美的转发解决方案来模拟它们很难做到绝对正确和绝对通用。
-
普通的 C++11 完美转发有什么问题,手头的情况?
-
您可以快速编写 90% 的用例解决方案,但要使其完美,需要考虑各种极端情况(例如转发
initializer_lists,或显式构造函数,或者其他;继承 ctors把所有这些都做好)。您还需要小心复制构造函数 (flamingdangerzone.com/cxx11/2012/06/05/is_related.html)...就我个人而言,我一直在使用 90% 的解决方案,并且无休止地推迟思考它,因为它看起来很痛苦:(
标签: c++ templates c++11 constructor clone