我正在尝试为头类的参考/文档创建一个更清晰的头文件,同时仍然认识到模板的便利性。所以我有一个快速的.h / .hpp文件
// mempool.h
namespace internal {
template<typename T,template<class> class Allocator>
class MemoryPool;
}
template<typename T,template<class> class Allocator = std::allocator>
class MemoryPool
{
private: internal::MemoryPool<T,Allocator> *pimpl;
public: MemoryPool();
public: virtual ~MemoryPool();
public: void flush() { return pimpl->flush(); }
public: T *find(T object) { return pimpl->find(object); }
public: T *pop() { return pimpl->pop(); }
public: void push(T object) { return pimpl->push(object); }
};
干净整洁。 然后是一个.hpp文件
// mempool.hpp
#include <memory>
#include <mutex>
namespace cext {
namespace memory {
#include "memorypool.h"
template<typename T,template<class> class Allocator>
MemoryPool<T,Allocator>::MemoryPool()
:pimpl(new internal::MemoryPool<T,Allocator>())
{
}
template<typename T,template<class> class Allocator>
MemoryPool<T,Allocator>::~MemoryPool()
{
delete pimpl;
}
namespace internal {
template<typename T,template<class> class Allocator = std::allocator>
class MemoryPool
{
private: std::mutex mtx;
private: Allocator<T> alloc;
public: MemoryPool()
:alloc()
{
//alloc.allocate(256);
}
public: ~MemoryPool()
{
//alloc.deallocate();
}
public: void flush()
{
mtx.lock();
puts("flush");
mtx.unlock();
}
public: T *find(T object)
{
mtx.lock();
puts("find");
mtx.unlock();
return nullptr;
}
public: T *pop()
{
mtx.lock();
puts("pop");
mtx.unlock();
return nullptr;
}
public: void push(T object)
{
mtx.lock();
puts("push");
mtx.unlock();
}
};
} // end internal
} // end cext
} // end memory
所以我不认为使用pimpl会为我做任何事情,因为用户需要#include .hpp文件。如果我没有弄错的话,对实现的更改将导致链接器更新,因此无法提高编译速度。考虑到我是如何#include .hpp文件中的.h文件,我可能会一起取消pimpl。
问:我想知道是否有一种干净的方式来显示模板的最小标题,就像我在.h文件中所做的那样,但仍然可以获得一些编译器加速?如果有其他方法可行,我不会选择pimpl。-Cheers
答案 0 :(得分:0)
如果需要为一组未知类型支持模板的隐式实例化,则必须使模板的实现对编译器可见。
然而,有一种类似于pimpl的有用的模板技术,我在类似的场景中使用过。这涉及将不依赖于模板参数类型的模板的实现“提升”到单独的类中。这是一个基于您的问题的示例 - 稍微修改以匹配我实现池分配器的方式:
namespace internal {
class MemoryPool
{
public:
// allocates up to 'count' blocks big enough to hold 'size' from 'storage'
MemoryPool(std::size_t size, std::size_t count, void* storage);
void* allocate(); // allocates a block big enough to hold 'size'
void deallocate(void* p); // deallocates the block pointed at by 'p'
};
}
template<typename T,template<class> class Allocator = std::allocator>
class MemoryPool : Allocator<T>, internal::MemoryPool
{
typedef Allocator<T> Alloc;
public: MemoryPool(std::size_t n, const Alloc& a = Alloc())
: Alloc(a), internal::MemoryPool(sizeof(T), n, Alloc::allocate(n))
{
}
public: ~MemoryPool();
public: T *poolNew(T object)
{
T* p = static_cast<T*>(internal::MemoryPool::allocate());
Alloc::construct(p, object);
return p;
}
public: void poolDelete(T* p)
{
Alloc::destroy(p);
return internal::MemoryPool::deallocate(p);
}
};
这具有允许将internal::MemoryPool
的实现隐藏在.cpp中的预期效果。