pimpl使模板编码更少杂乱 [英] pimpl to make template coding less cluttered

查看:157
本文介绍了pimpl使模板编码更少杂乱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个更干净的头文件以供参考/头文件类的文档,同时仍然识别模板的方便。所以我有一个快速的.h / .hpp文件

I'm attempting to create a cleaner header file for reference/documentation of header classes while still recognizing the convenience of templates. So I've got a quick .h / .hpp file

// 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); }
};

尼斯和干净。
然后a .hpp文件

Nice and clean. Then a .hpp file

// 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文件。对实现的更改将导致链接器更新,所以没有编译速度提升,如果我没有错。我可能可以把所有的pimpl一起放在一起,因为我是包括.h文件中的.hpp文件中的.h文件。

So I don't think using pimpl did anything for me since users would need to #include the .hpp file. Changes to implementation would cause linker updates so no compile speed boost, if I'm not mistaken. I could probably do away with the pimpl all together given how I am #including the .h file in the .hpp file.

问:我想知道if有一个干净的方式显示模板的最小头,我上面在.h文件中做了,但仍然得到一些编译器加速?

Q: I'd like to know if there is a clean way to display a minimal header for a template as I've done above in the .h file, but still get some compiler speed-up's? I'm not set on pimpl if there are other methodologies that work.

-Cheers

推荐答案

如果您需要为一组未知类型的模板支持隐式实例化,则必须让该模板的实现对编译器可见。

If you need to support implicit instantiation of your template for an unknown set of types, you must make the implementation of the template visible to the compiler.

但是,有一个有用的模板技术类似于我在类似的情况下使用的pimpl。这涉及将不依赖于模板参数的类型的模板的实现提升到单独的类中。这里有一个基于你的问题的例子 - 稍微修改以匹配我将实现池分配器的方式:

However, there is a useful template technique similar to pimpl that I've used in a similar scenario. This involves 'lifting' the implementation of the template that does not depend on the types of the template parameters into a separate class. Here's an example based on your problem - modified slightly to match the way I would implement a pool allocator:

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中。

This has the desired effect of allowing the implementation of internal::MemoryPool to be hidden in the .cpp.

这篇关于pimpl使模板编码更少杂乱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆