0

我需要一种通用的方法来创建任何类型的实例。此任务需要从非模板对象执行,因此我目前正在使用如下接口:

class Interface
{
public:
  virtual void PlacementCopy( void *data, const void *src ) const = 0;
  virtual void PlacementNew( void *data ) const = 0;
  virtual void PlacementDelete( void *data ) const = 0;
  virtual void Delete( void *data) const = 0;
  virtual void Copy( void *dest, const void *src ) const = 0;
  virtual void NewCopy( void **dest, const void *src ) const = 0;
  virtual void *New( ) const = 0;
};

这都是自定义反射系统的一部分,因此它的使用方式如下:

int *p = META( int )->Interface->New( );
*p = 10;

这通过创建一个派生自 的模板化对象来工作Interface,该对象包含要构造的类型。Interface 中的New运算符默认构造类型:

template <typename T>
class Derived : public Interface
{
  virtual void *New( void ) const override
  {
    return new T( );
  }
};

问题:以这种方式构造的所有类型都必须提供默认构造函数。我想以某种方式允许将任意参数传递给相关类型的构造函数。

我不知何故需要能够做到:

MetaInfo *meta = META( SomeType );
SomeType *object = meta->New( arg1, arg2 );

在实现中可能看起来像这样:

template <typename T>
Derived : public Interface
{
  template <typename ... Args>
  virtual void *New( Args&& ... args ) const override
  {
    new T( std::forward<Args>( args ) ... );
  }
};

MetaInfo对象不是模板类型,因此很难提出参数转发解决方案。我不能简单地模板化类中的New方法Derived,因为您不能模板化虚拟方法。

如果没有一些疯狂的代码预处理,我的要求是否可能?

4

1 回答 1

0

在一些朋友的帮助下,我最终收集了一个解决方案!

所以最大的问题是在反射中注册的所有类型都需要一个默认构造函数。为了解决这个问题,您可以使用 SNIFAE 检查默认构造函数是否存在。

struct HasDefaultCtor
{
  template <typename U>
  static int32 SFINAE( decltype( U( ) ) * );
  template <typename U>
  static int8 SFINAE( ... );

  static const bool value = sizeof( SFINAE<T>( NULL ) ) == sizeof( int32 );
};

除此之外,所有非默认构造函数都必须在反射系统中手动注册,或者使用预构建步骤工具生成。额外的 SNIFAE 检查可用于类型检查并确保注册的构造函数实际上与类中的真实构造函数匹配。对于实际调用New运算符,需要进行一些运行时解析,以便确定需要什么构造函数来匹配New调用。

我希望这是有道理的,并且最终对将来的某人有用。

我还对复制构造函数进行了 SNIFAE 检查:

template <typename T>
struct HasCopyCtor
{
  static T MakeT( void );

  template <typename U>
  static int32 SFINAE( decltype( U( MakeT( ) ) ) * );
  template <typename U>
  static int8 SFINAE( ... );

  static const bool value = sizeof( SFINAE<T>( NULL ) ) == sizeof( int32 );
};
于 2013-04-20T22:26:36.243 回答