宏生成可疑错误

时间:2014-02-03 14:43:32

标签: c++ templates macros

我一直用C ++编写内存管理器,并且一直使用宏代替传统的new调用。这背后的动力是双重的:我需要捕获有关所请求分配的类型信息,并且我想生成干净的语法。对于宏来说,这是一项艰巨的任务。但这就是我想出的:

#define anew( TYPE ) new ( Allocator::Instance( )->Allocate<TYPE>( ) ) TYPE

它调用分配器在内存池中为TYPE类型的对象(相对于宏)创建一个点。然后它使用Allocate返回的指针作为放置new的参数,允许构造函数在这个刚刚“分配”的内存块上运行。到目前为止有道理。因此,在正常使用中,这是它扩展的方式:

Obj* a = anew( Obj )( );
Obj* a = new ( Allocator::Instance( )->Allocate<Obj>( ) ) Obj( );

这很棒!但是当我尝试将它与具有多个参数的模板化类一起使用时,它会爆炸(我的意思是它会产生错误)。

Obj<int, bool>* a = anew( Obj<int, bool> )( );

这抱怨没有足够的类型参数提供给模板参数。经过一些戳之后,我明白这是因为模板参数中的逗号。在这种情况下,如何解决此问题

更好的是,还有更好的方法吗?我认为将它作为一个宏是有意义的,因为我真的只想在这里进行一些直接文本替换。但是,从以不同的方式解决这个问题,我能获得什么吗是否可以在不使用宏的情况下完成此操作?我尝试过这条路线,出现的问题是调用构造函数。以下代码无效,但它会很好:

Obj* a = anew<Obj>( );

其中括号只能对应给定类型的有效构造函数。

非常感谢任何帮助。谢谢!

[编辑]

虽然Variadic Macros也解决了我的问题,但我在下面选择的答案是我认为是我问题的最佳C ++解决方案。谢谢大家这么快解决这个问题。

1 个答案:

答案 0 :(得分:7)

使用C ++ 11,您可以这样做:

template <typename T,typename... Args>
T* anew(Args&&... args)
{
  return new(Allocator::Instance()->Allocate<T>()) T(std::forward<Args>(args)...);
}

现在您可以使用此表单:

Obj* a = anew<Obj>( );

并将参数的任何内容(或任何内容)传递给构造函数。

std::forward是允许参数从一个函数转发到另一个函数的一般机制。它依赖于右值引用的参数和参数与模板的折叠,使其成为正确有效地传递左值和右值的地方。结合可变参数,这允许以这种方式完美地转发任意数量的参数。