宏产生可疑错误

Macro Producing Suspicious Errors

本文关键字:错误      更新时间:2023-10-16

我一直在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宏也解决了我的问题,但我在下面选择的答案是我认为是我问题的最佳C 解决方案。谢谢大家如此迅速地解决此问题。

使用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是允许参数从一个函数转发到另一个函数的一般机制。它依赖于RVALUE参考的技巧和与模板的参考折叠,以使其正确,有效地传递LVALUES和RVALUES。结合变异性,这允许以这种方式完美地转发任何数量的参数。