正确组织最终用户无法访问的模板化和非模板化功能的混合

2023-12-26

在我正在进行的一个项目中,我目前正在实现一个模板化的算法。我在组织函数声明和定义时遇到了一些问题,因为涉及模板(我问了一个问题here https://stackoverflow.com/q/25139535/884412关于如何处理非模板化函数与模板函数“分组”在一起)。然而,这让我想知道这些文件的一般正确组织方式。

我想分开所有的定义 from 所有声明(只是为了可读性目的,即使我必须将模板化定义包含回声明中)。

我得到的答案建议组织如下:

  • 声明文件algo.h对于所有函数声明
  • The 模板化的定义文件algo.tpp它将被包含在algo.h(模板需要在编译时声明)
  • (非模板化)定义文件algo.cpp不包含在任何地方。

如果所有定义的函数都应该对最终用户可见(即所有声明都在algo.h文件)。然而,有时我喜欢把我的大功能分解成更小的功能,但是我希望最终用户只能访问“大功能”,而不是其子部分。 在非模板设置中,我会这样做:

  • 声明文件algo.h将包含仅针对最终用户的声明(将通过包含访问)
  • 这些函数的定义将转到algo.cpp
  • 子功能的定义(和声明)将只在场 in the algo.cpp,允许我的大功能 in algo.cpp(其中声明的algo.h)使用它们,但不让最终用户可以访问它们。

如果这些子功能本身不是模板化的,而是由模板化函数使用的,那么这将不再起作用。模板化的子功能可以进入.tpp文件,被模板化的“大函数”使用,一切都很好。

然而,如果这些功能不是模板化的,它们会导致多重定义错误(即我之前的问题是关于什么的 https://stackoverflow.com/q/25139535/884412)如果放置在.tpp文件。另一方面,如果它们位于单独的.cpp文件中,它们要么可供最终用户访问(如果我将声明放在.h文件),或者无法访问旨在使用它们的大函数(如果我不将声明放在.cpp file).

组织功能的正确方法是什么,一些模板化和some not,其中一些应该可供最终用户访问,而另一些则不能访问到多个文件中?

理想情况下,(为了完整性),我正在寻找的答案将解决以下内容的放置(在.h, .tpp, .cpp,或其他适当的文件):

  • 模板化的客户端函数
  • 非模板化客户端函数
  • 模板化的客户端函数
  • 非模板化客户端函数
  • 上述所有内容的声明(当使用声明时)

短的近乎伪代码我想要的功能示例(没有文件分隔)

    // Templated sub-functionality, used by bigFunctionality,
    // but ideally not accessible to the end-user
    // This might not be possible since it is templated,
    // so I am content with putting it in the .tpp file
    template <typename Compare>
    void subFunctionality(Compare order, .. args ..){ /* impl */ }

    // Non-templated sub-functionality, used by
    // bigFunctionality, but NOT accessible to the end-user
    void moreSubFunctionality(.. args ..) { /* impl */ }


    // the main functionality, meant to be
    // accessible to everybody across all files:
    template <typename Compare>
    void bigFunctionality( .. non-templated args ..., Compare order){
         subFunctionality(order, .. args ..);
         moreSubFun(.. args ..);
         // more stuff
    }

再次,我正在研究如何将其分成多个文件(即使它们彼此包含在一起,因为它必须使用模板完成),部分是为了可读性目的,部分是为了可访问性。

只是为了澄清,这些是算法 --> 函数,而不是类。 (我知道将模板化和非模板化函数放入同一个模板化类中可以解决我的问题)。

PS: I know the title of the question is very big and long, so if somebody has an idea about shortening it, I would be more than happy for the suggestions/edits


这是 C++ 中缺少模块的一个不幸的副作用:声明的内容必然是可见的。

一般来说,指导原则是简单地使用“私有”命名空间(嵌套在用户可见的命名空间内):

  • 使用清晰的名称(例如internal)
  • 并仅在您的名称空间中声明这些辅助函数.tpp file

然后,您记录该命名空间是内部的且不适合客户端调用者。如果可能,您还可以对命名空间/函数进行注释,以便不会为它们生成文档。

此时,这些函数是明显是私人的 and hidden.

如果您想更进一步,您可以简单地声明它们private in a class(*),然后只有your函数是friend这个班级的。然后,任何使用它们的尝试都会导致编译器发出错误:它们是可见的,但是无法访问。然而,大多数人(从 Boost 开发人员开始)只是不打扰,我当然也不打扰。

(*) The class本质上取代了私有命名空间。

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

正确组织最终用户无法访问的模板化和非模板化功能的混合 的相关文章

  • C 编程 - 文件 - fwrite

    我有一个关于编程和文件的问题 while current NULL if current gt Id Doctor 0 current current gt next id doc current gt Id Doctor if curre
  • 我如何才能等待多个事情

    我正在使用 C 11 和 stl 线程编写一个线程安全队列 WaitAndPop 方法当前如下所示 我希望能够将一些内容传递给 WaitAndPop 来指示调用线程是否已被要求停止 如果 WaitAndPop 等待并返回队列的元素 则应返回
  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • 在结构中使用 typedef 枚举并避免类型混合警告

    我正在使用 C99 我的编译器是 IAR Embedded workbench 但我认为这个问题对于其他一些编译器也有效 我有一个 typedef 枚举 其中包含一些项目 并且我向该新类型的结构添加了一个元素 typedef enum fo
  • 不同枚举类型的范围和可转换性

    在什么条件下可以从一种枚举类型转换为另一种枚举类型 让我们考虑以下代码 include
  • 堆栈溢出:堆栈空间中重复的临时分配?

    struct MemBlock char mem 1024 MemBlock operator const MemBlock b const return MemBlock global void foo int step 0 if ste
  • 将 VSIX 功能添加到 C# 类库

    我有一个现有的单文件生成器 位于 C 类库中 如何将 VSIX 项目级功能添加到此项目 最终目标是编译我的类库项目并获得 VSIX 我实际上是在回答我自己的问题 这与Visual Studio 2017 中的单文件生成器更改 https s
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • 重载<<的返回值

    include
  • SolrNet连接说明

    为什么 SolrNet 连接的容器保持静态 这是一个非常大的错误 因为当我们在应用程序中向应用程序发送异步请求时 SolrNet 会表现异常 在 SolrNet 中如何避免这个问题 class P static void M string
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect
  • WPF/C# 将自定义对象列表数据绑定到列表框?

    我在将自定义对象列表的数据绑定到ListBox in WPF 这是自定义对象 public class FileItem public string Name get set public string Path get set 这是列表
  • 如何从两个不同的项目中获取文件夹的相对路径

    我有两个项目和一个共享库 用于从此文件夹加载图像 C MainProject Project1 Images 项目1的文件夹 C MainProject Project1 Files Bin x86 Debug 其中有project1 ex
  • 将控制台重定向到 .NET 程序中的字符串

    如何重定向写入控制台的任何内容以写入字符串 对于您自己的流程 Console SetOut http msdn microsoft com en us library system console setout aspx并将其重定向到构建在
  • 混合 ExecutionContext.SuppressFlow 和任务时 AsyncLocal.Value 出现意外值

    在应用程序中 由于 AsyncLocal 的错误 意外值 我遇到了奇怪的行为 尽管我抑制了执行上下文的流程 但 AsyncLocal Value 属性有时不会在新生成的任务的执行范围内重置 下面我创建了一个最小的可重现示例来演示该问题 pr
  • 是否可以在 .NET Core 中将 gRPC 与 HTTP/1.1 结合使用?

    我有两个网络服务 gRPC 客户端和 gRPC 服务器 服务器是用 NET Core编写的 然而 客户端是托管在 IIS 8 5 上的 NET Framework 4 7 2 Web 应用程序 所以它只支持HTTP 1 1 https le
  • IEnumreable 动态和 lambda

    我想在 a 上使用 lambda 表达式IEnumerable
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new
  • C++ 标准是否指定了编译器的 STL 实现细节?

    在写答案时this https stackoverflow com questions 30909296 can you put a pimpl class inside a vector我遇到了一个有趣的情况 这个问题演示了这样一种情况
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个

随机推荐

  • 在 foreach 循环外部使用 foreach 循环的变量

    我有一个 foreach 循环 我在循环内创建了一个字符串 但我想在循环外使用 var 这可能吗 List
  • .NET版本和C#版本之间的关系? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 如何确定可以针对特定 NET Framework 版本使用哪个版本的 C 我读过了 https sta
  • Git 精选语法和合并分支

    所以我之前已经做过无数次樱桃挑选 看来我现在必须在生活中失败 我正在尝试从一个分支挑选到另一个分支 这应该很容易 但是我收到了关于它是合并的错误 但是没有给出 m 吗 git cherry pick a8c5ad438f6173dc34f6
  • Mono无法打开sqlite数据库

    我正在尝试对 sqlite v3 数据库进行非常基本的连接 并且我正在使用 monodevelop 3 0 和 Mono 2 10 但无法连接到数据库 我可以让应用程序创建数据库 但随后它尝试连接到数据库时立即失败 有什么建议么 我从不同的
  • 查找可点击的元素

    有没有办法找到用 click 或 live click 指定的所有可点击元素 如果单击任何此类元素 我想执行一些操作 container bind click function event actions 这个捕获所有点击 Thanks 这
  • 如何使用时区偏移格式化 LocalDateTime

    我尝试这样做 ZoneOffset zoneOffset ZoneOffset ofHours 3 DateTimeFormatter fmt DateTimeFormatter ofPattern HH mm ss LocalDateTi
  • 如何确定我的 iOS 设备是否有手电筒?

    在我的应用程序中 我可以选择手电筒 然而 只有 iPhone 4 和 iPhone 4S 有手电筒灯 其他设备没有手电筒灯 如何找到当前设备型号 请帮我 提前致谢 您不应使用设备型号作为是否存在某项功能的指示符 相反 请使用 API 来准确
  • blur.js 尝试请求“none”并且 div 未扩展 100%

    我正在尝试使用http blurjs com http blurjs com 模糊标题栏的标题图像的背景 然而 它给了我一个有趣的错误 我似乎无法追踪 这可能与主要代码和兼容性有关 但我不确定 http jordan rave5 com t
  • 在 Numpy(或 Scipy)中计算斜率

    我正在尝试找到使用 Numpy 和 Scipy 计算斜率的最快 最有效的方法 我有一组由三个 Y 变量和一个 X 变量组成的数据集 我需要计算它们各自的斜率 例如 我可以轻松地一次一行执行此操作 如下所示 但我希望有一种更有效的方法来执行此
  • 按下 iOS swift 后更改 UIBarButtonItem 图标

    In the viewDidload方法 我声明了一个按钮并设置了 RightBarButton let btnFavourite UIButton frame CGRectMake 0 0 30 30 btnFavourite addTa
  • 找不到任何与 com.google.android.gms 匹配的版本:strict-version-matcher-plugin:[15.0.0, 16.0.0)

    项目一直运行良好 直到前两天突然出现错误 我不知道如何解决它 因为我已经做了我能做的一切 包括重新安装 android studio 和 gradle 无法解析配置 app debugCompileClasspath 的所有文件 找不到与
  • Array.push 返回推送值?

    是否有任何实质性原因需要修改Array push 返回推送的对象而不是新数组的长度可能是一个坏主意 我不知道这是否已经被提议或询问过 谷歌搜索只返回了大量与当前功能相关的问题Array push 这是此功能的示例实现 请随意更正它 func
  • ChildNode 类型上不存在属性“tagName”[Typescript]

    我正在从父节点循环子节点 我想访问子节点的 tagName 但错误是 tagName 在类型 ChildNode 上不存在 const contentParsed new DOMParser parseFromString content
  • 创建 LocalDB 以从 Visual Studio SQL 项目进行测试

    我正在尝试为我的项目创建集成测试 我需要测试一个通过存储库调用存储过程的控制器 应在每次运行某些范围的测试时创建一个空数据库 所以我将实施以下步骤 Create LocalDB 运行一些预脚本 以添加测试数据 Run test 运行一些后脚
  • GIMP的图层合成/混合方法

    在我寻求为 Matlab 中的图像混合工具添加 Alpha 功能时 我遇到了一些障碍 其中 我一直在使用these http ssp impulsetrain com porterduff html links http www adobe
  • 显示一个 div,单击时隐藏所有其他 div

    我有一个简单的图像 视频库 我想用 jQuery 制作动画 我想要做的就是 当有人点击链接时 big具有相同ID的div被设置为display block opacity 1所有其他 div 都设置为display none opacity
  • 将多通道 PyAudio 转换为 NumPy 数组

    我能找到的所有例子都是单声道的 CHANNELS 1 如何使用 PyAudio 中的回调方法读取立体声或多声道输入并将其转换为 2D NumPy 数组或多个 1D 数组 对于单声道输入 类似这样的工作 def callback in dat
  • NodeJS 中的 Rijndael 256 CBC PKCS7 加密/解密

    我正在为一项服务构建一个 NodeJS 客户端 该服务使用 256 位块 Rijndael CBC 和 PKCS7 填充来加密数据 我看过 NodeJS 中的几个 Rijndael 实现 但似乎没有一个提供我正在寻找的组合 如何使用Rijn
  • 从 python hook 调用 Mercurial 命令(“hg update”)

    我在 Windows 2008 64 位和 IIS 上设置了 Mercurial hgweb 存储库的位置是网络共享 我想在存储库上创建一个挂钩 以在更改组上发出 hg update 命令 我无法使用外部挂钩 因为这会以网络共享作为工作目录
  • 正确组织最终用户无法访问的模板化和非模板化功能的混合

    在我正在进行的一个项目中 我目前正在实现一个模板化的算法 我在组织函数声明和定义时遇到了一些问题 因为涉及模板 我问了一个问题here https stackoverflow com q 25139535 884412关于如何处理非模板化函