使用msvc2008重载全局新运算符问题

时间:2012-06-05 16:24:40

标签: c++ visual-c++ memory-management new-operator

我在自己的图书馆工作,我有自己的分配器。我已经宣布了一个像这样的通用界面:

class MyAllocator
{
public:
  void * allocate(size_t size);
  void * allocate(size_t size, size_t align);
  void   deallocate(void *);

  //...

};

现在,如果我想用这样的分配器分配C ++对象,我必须以这种方式使用placement new:

MyAllocator a;
MyObject * o = new(a.allocate(sizeof(MyObject))) MyObject(param1, param2, ...);

这当然非常有效。现在,很久以前我想创建一个全局分配器,它将分配器作为参数,以避免重复的sizeof()。所以我来这里:

template< typename AllocatorT >
inline
void *operator new(size_t n_bytes, AllocatorT & allocator)
{
    return allocator.allocate(n_bytes);
}

有了这个,我可以打电话:

MyAllocator my_alloc;
MyObject * o = new(my_alloc) MyObject(param1, param2);

语法很干净,很酷。 这基本上也很好用(使用gcc和msvc2010),但今天,当我在msvc2008中尝试过它时,我遇到了错误:那是因为 msvc2008编译器从该模板参数中被愚弄,因此,当我包含一个使用正常放置的标头时,新的[几乎每个stl标头都包含对一个新放置的调用,例如矢量,集等]编译器将使用我的全局new的模板化版本,而不是新的贴图,导致一个明显的错误:类型&#39; void *&#39;不是类/结构,当然也没有allocate()成员函数。

现在,问题出现了:

  • 这是msvc2008的错误吗?使用gcc 4.4.0,4.4.5和msvc2010,它可以很好地工作。
  • 我在写一个接受分配器引用的模板化全局新运算符时错了吗?我的意思是,这个东西可能是一个模糊的语法,可以让编译器容易上当,经常导致错误,我应该放弃这个想法,或者这可以通过其他方式实现吗?如前所述,它使用普通的placement new来大大降低了使用自定义分配器进行C ++对象分配的复杂性。
  • 通常,如果我们有:

    void f(void *); // 1 模板&LT; typename A&gt; f(A&amp;); // 2

我们打电话:

void * void_ptr = something();
f(void_ptr);

当然这里第一个版本被调用。

为什么在使用operator new的模板化版本的msvc2008中似乎没有发生这种情况?

0 个答案:

没有答案