pimpl 使模板编码不那么混乱

2024-02-14

我正在尝试创建一个更清晰的头文件,以供头类的参考/文档使用,同时仍然认识到模板的便利性。所以我有一个快速的 .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 文件。如果我没记错的话,对实现的更改会导致链接器更新,因此不会提高编译速度。考虑到我在 .hpp 文件中 #include .h 文件,我可能可以一起取消 pimpl。

问:我想知道是否有一种干净的方法来显示模板的最小标头,就像我在上面在 .h 文件中所做的那样,但仍然可以获得一些编译器加速?如果还有其他可行的方法,我不会选择 pimpl。

-Cheers


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

不过,有一种类似于 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中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

pimpl 使模板编码不那么混乱 的相关文章

  • Tensorflow 中的自定义资源

    由于某些原因 我需要为 Tensorflow 实现自定义资源 我试图从查找表实现中获得灵感 如果我理解得好的话 我需要实现3个TF操作 创建我的资源 资源的初始化 例如 在查找表的情况下填充哈希表 执行查找 查找 查询步骤 为了促进实施 我
  • 将处理后的图形绘制到另一个图形中

    我想将一个经过处理的图形绘制到另一个图形中 I have two graphics var gHead Graphics FromImage h var gBackground Graphics FromImage b Transform
  • 当我单击 C# 中的“取消”按钮时重定向到新页面(Web 部分)

    Cancel button tc new TableCell btnCancel new Button btnCancel Text Cancel btnCancel Click new EventHandler btnCanel Clic
  • Linux TUN/TAP:无法从 TAP 设备读回数据

    问题是关于如何正确配置想要使用 Tun Tap 模块的 Linux 主机 My Goal 利用现有的路由软件 以下为APP1和APP2 但拦截并修改其发送和接收的所有消息 由Mediator完成 我的场景 Ubuntu 10 04 Mach
  • std::map 和二叉搜索树

    我读过 std map 是使用二叉搜索树数据结构实现的 BST 是一种顺序数据结构 类似于数组中的元素 它将元素存储在 BST 节点中并按其顺序维护元素 例如如果元素小于节点 则将其存储在节点的左侧 如果元素大于节点 则将其存储在节点的右侧
  • TextBox 焦点的 WinForms 事件?

    我想添加一个偶数TextBox当它有焦点时 我知道我可以用一个简单的方法来做到这一点textbox1 Focus并检查布尔值 但我不想那样做 我想这样做 this tGID Focus new System EventHandler thi
  • 如何在 VS 中键入时显示方法的完整文档?

    标题非常具有描述性 是否有任何扩展可以让我看到我正在输入的方法的完整文档 我想查看文档 因为我可以在对象浏览器中看到它 其中包含参数的描述和所有内容 而不仅仅是一些 摘要 当然可以选择查看所有覆盖 它可能是智能感知的一部分 或者我不知道它并
  • VS30063:您无权访问 https://dev.azure.com

    我正在尝试在 asp net core 2 1 mvc 应用程序中使用以下代码连接 Azure DevOps Uri orgUrl new Uri https dev azure com xxxxx String personalAcces
  • 是否有与 C++11 emplace/emplace_back 函数类似的 C# 函数?

    从 C 11 开始 可以写类似的东西 include
  • 为什么 std::allocator 在 C++17 中丢失成员类型/函数?

    一边看着std 分配器 http en cppreference com w cpp memory allocator 我看到成员 value type pointer const pointer reference const refer
  • Xamarin Android:获取内存中的所有进程

    有没有办法读取所有进程 而不仅仅是正在运行的进程 如果我对 Android 的理解正确的话 一次只有一个进程在运行 其他所有进程都被冻结 后台进程被忽略 您可以使用以下代码片段获取当前正在运行的所有 Android 应用程序进程 Activ
  • C++派生模板类继承自模板基类,无法调用基类构造函数[重复]

    这个问题在这里已经有答案了 我试图从基类 模板 继承 派生类也是模板 它们具有相同的类型 T 我收到编译错误 非法成员初始化 Base 不是基类或成员 为什么 如何调用基类构造函数 include
  • 两组点之间的最佳匹配

    I ve got two lists of points let s call them L1 P1 x1 y1 Pn xn yn and L2 P 1 x 1 y 1 P n x n y n 我的任务是找到它们点之间的最佳匹配 以最小化它
  • 事件日志写入错误

    很简单 我想向事件日志写入一些内容 protected override void OnStop TODO Add code here to perform any tear down necessary to stop your serv
  • 用于从字符串安全转换的辅助函数

    回到 VB6 我编写了一些函数 让我在编码时无需关心字符串的 null 和 数字的 null 和 0 等之间的区别 编码时 没有什么比添加特殊情况更能降低我的工作效率了用于处理可能导致一些不相关错误的数据的代码 9999 10000 如果我
  • Silverlight Datagrid:在对列进行排序时突出显示整个列

    我的 Silverlight 应用程序中有一个 DataGrid 我想在对该列进行排序时突出显示整个列 它在概念上与上一个问题类似 Silverlight DataGrid 突出显示整列 https stackoverflow com qu
  • 如何检测 C# 中该字典键是否存在?

    我正在使用 Exchange Web 服务托管 API 和联系人数据 我有以下代码 即功能性的 但并不理想 foreach Contact c in contactList string openItemUrl https service
  • 内核开发和 C++ [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 从我know https stackoverflow com questions 580292 what languages are windo
  • 过度使用委托对性能来说是一个坏主意吗? [复制]

    这个问题在这里已经有答案了 考虑以下代码 if IsDebuggingEnabled instance Log GetDetailedDebugInfo GetDetailedDebugInfo 可能是一个昂贵的方法 因此我们只想在调试模式
  • 在基类集合上调用派生方法

    我有一个名为 A 的抽象类 以及实现 A 的其他类 B C D E 我的派生类持有不同类型的值 我还有一个 A 对象的列表 abstract class A class B class A public int val get privat

随机推荐

  • 有没有 numpy group by 函数?

    numpy 中是否有任何函数可以按第一列将该数组分组到下面 我在互联网上找不到任何好的答案 gt gt gt a array 1 275 1 441 1 494 1 593 2 679 2 533 2 686 3 559 3 219 3 4
  • Bootstrap 3 中的垂直对齐字形

    我有一个这样的字形 div class col xs 4 col sm 2 span class glyphicon glyphicon circle arrow up glyphicon large span div glyphicon
  • 在 WordPress 中获取页面(无帖子)的精选图像

    我需要显示所有页面的特色图像 而不是帖子 我有这个代码 img src class header img alt 但这仅显示一张特色图像 太感谢了 您可以简单地使用 WP Query 来获取它 loop new WP Query array
  • Yii2 自定义分页联合查询

    我想在 Yii2 中实现自定义分页 这是我的代码 connection Yii app gt getDb name GET name query SELECT name FROM user WHERE name LIKE name UNIO
  • Python 将十进制转换为十六进制

    我这里有一个函数可以将十进制转换为十六进制 但它以相反的顺序打印它 我该如何解决它 def ChangeHex n if n lt 0 print 0 elif n lt 1 print n else x n 16 if x lt 10 p
  • jQuery:无限滚动和后退按钮

    好吧 我知道这会给每个人带来问题 也给我带来问题 我在客户的网站上使用无限滚动插件 结合同位素插件按顺序加载他们的产品 问题是 因为他们有 1000 种产品 任何浏览该网站然后点击进入产品的人 当他们点击按后退按钮 它们将返回到顶部 或第一
  • 将多个文件导入到 R 中的单个合并数据框中

    我有 8 个 CSV 文件都在同一目录中 需要将它们导入到 R 中的单个数据框中 它们都遵循相同的命名约定 dataUK 1 csv dataUK 2 csv 等 并且具有完全相同的功能列的结构 我已经成功地使用以下方法创建了所有文件名 包
  • VS 2012 中的可变参数模板(Visual C++ 2012 年 11 月 CTP)

    我安装了Visual C 编译器 2012 年 11 月 CTP http www microsoft com en us download details aspx id 35515并创建了一个 C 控制台项目 我把这个写在 templa
  • 单态与单态

    当人们使用单态模式而不是单例来维护全局对象时 会出现什么情况 编辑 我知道什么是单例模式和单态模式 在很多场景中也实现了 Singleton 只是想知道MonoState模式需要实现的场景 案例 例如 我需要在 Windows 窗体应用程序
  • 如何设置 LIBUSB_INCLUDE_DIR

    我正在尝试为arm交叉编译libftdi 当我运行 Cmake 时 我得到 CMake Error The following variables are used in this project but they are set to N
  • 在 Iphone SDK 中显示 GPS 可用性和准确性

    如何编程以在 iPhone 中显示 GPS 可用性和准确度级别 并且它必须擦除标签中先前的纬度 经度信息 iOS sdk 中有一个类叫做 CLLocationManager 浏览 XCode 中的文档或查找一些示例 http mobileo
  • Jetpack Compose:如何以编程方式 onClick 将主题从浅色模式更改为深色模式

    TL DR 更改主题并在单击时在浅色和深色主题之间重新组合应用程序 你好 我有一个有趣的问题 我一直在努力解决 希望得到一些帮助 我正在尝试实现一个设置屏幕 让用户更改应用程序的主题 选择与系统设置匹配的深色 浅色或自动 我已成功设置主题动
  • 将值传递给 onclick [重复]

    这个问题在这里已经有答案了 如果我使用循环创建大量 HTML 元素 例如 for i 1 i lt 100 i var my element document createElement td row appendChild my elem
  • jquery Mobile url 添加 # 标签,该标签会破坏 Internet Explorer 中的表单

    大家好 我的问题是我有一个 jquery 移动网站 其链接与普通网站类似 例如 a href http mysite com login Login a 现在 当他们在 Firefox 等中转到该页面时 它会转到 http mysite c
  • c++: LLDB + Python - 如何在 python 脚本中打印 std::string

    我正在尝试 LLDB python 以便更好地将 json 字符串打印到文件中 对于给定的 std string 变量 称为缓冲区 我在 python 断点脚本中尝试了以下操作 以便漂亮地打印到文件中 全部都不成功 json dump fr
  • 使用 Selenium Webdriver 与 Stripe Card Element iFrame 交互 - Cucumber/Selenium Java

    我有一个表单 我想在 Java 中使用 Cucumber 和 Selenium Webdriver 来自动化 在这个表单中 我们有一个从 Stripe 中使用的卡片元素 我们称之为 div 剩下的由 stripe 完成 我不确定这是否是 i
  • 如何使用我的 flutter API 在表格日历上显示事件

    我有用于显示事件日历的 UI 并且需要显示 API 中的事件 但我不知道该怎么做 我尝试更改 event 上的列表 但没有响应 我需要在日历上显示它 以便我的公司日历可以显示该活动 这是我的 UI 日历 import package int
  • 新的 Firebase Facebook 登录

    我正在尝试使用新的 Firebase 平台登录 Facebook 这是 Facebook 登录的代码 let facebookLogin FBSDKLoginManager facebookLogin logInWithReadPermis
  • Python 文件关键字参数?

    在命令行中 我可以将参数传递给 python 文件 如下所示 python script py arg1 arg2 我可以找回arg1 and arg2 within script py as import sys arg1 sys arg
  • pimpl 使模板编码不那么混乱

    我正在尝试创建一个更清晰的头文件 以供头类的参考 文档使用 同时仍然认识到模板的便利性 所以我有一个快速的 h hpp 文件 mempool h namespace internal template