我们有一个提供C接口的库extern "C",并且是从C代码中使用的,但是它内部使用STL容器和一些C++功能(如RAII)以方便使用.
现在有一个新的要求,即库应该能够指向来自客户端代码的自定义malloc和free函数,并将其用于内部的分配.我可以将它们放入库的上下文结构中,并在需要的地方使用它们,但是将它们与STL一起使用是令人费解的......
我查看了allocator类,但似乎STL容器必须能够使用默认构造函数来创建分配器,似乎没有办法将这些指针放入它们中,让它们通过它们调用来进行分配.
是否有可能以线程安全的方式(不使用全局变量)来解决这个问题?
我查看了allocator类,但似乎STL容器必须能够使用默认构造函数来创建分配器
这不是真的,所有容器都可以使用显式的allocator构造,因此您可以创建allocator对象,然后将其传递给容器.
extern "C"
{
typedef void* (*allocation_function)(size_t);
typedef void (*deallocation_function)(void*);
}
template<typename T>
class Allocator
{
public:
typedef T value_type;
Allocator(allocation_function alloc, deallocation_function dealloc)
: m_allocate(alloc), m_deallocate(dealloc)
{ }
template<typename U>
Allocator(const Allocator<U>& a)
: m_allocate(a.m_allocate), m_deallocate(a.m_deallocate)
{ }
T* allocate(size_t n)
{ return static_cast<T*>(m_allocate(n * sizeof(T))); }
void deallocate(T* p, size_t)
{ m_deallocate(p); }
private:
template<typename U>
friend class Allocator<U>;
template<typename U>
friend bool operator==(const Allocator<U>&, const Allocator<U>&);
allocation_function m_allocate;
deallocation_function m_deallocate;
};
template<typename T>
bool operator==(const Allocator<T>& l, const Allocator<T>& r)
{ return l.m_allocate == r.m_allocate; }
template<typename T>
bool operator!=(const Allocator<T>& l, const Allocator<T>& r)
{ return !(l == r); }
Allocator<int> a(custom_malloc, custom_free);
std::vector<int, Allocator<int>> v(a);
Run Code Online (Sandbox Code Playgroud)
如果您还没有使用C++ 11,那么您需要为分配器提供更多成员以满足旧的要求,但上面的那些成员对C++ 11来说是可以的.在C++ 03中使用自定义分配器很困难而且无法移植,因此如果需要,您应该使用C++ 11编译器.