我在自己的图书馆工作,我有自己的分配器。我已经宣布了一个像这样的通用界面:
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()成员函数。
现在,问题出现了:
通常,如果我们有:
void f(void *); // 1 模板&LT; typename A&gt; f(A&amp;); // 2
我们打电话:
void * void_ptr = something();
f(void_ptr);
当然这里第一个版本被调用。
为什么在使用operator new的模板化版本的msvc2008中似乎没有发生这种情况?