是否永远不可能编写仅限标题的库?

soo*_*iln 14 c++ header-only

是否有这样的依赖模式,不可能只保留头文件中的所有内容?如果我们只对每个标题强制执行一个类的规则怎么办?

出于这个问题的目的,让我们忽略静态的东西:)

Bil*_*eal 7

我知道标准C++中没有任何功能,除了你已经提到的静态,它需要一个库来定义一个完整的翻译单元(而不是只有标题).但是,建议不要这样做,因为当您这样做时,您会强制所有客户端在库更改时重新编译整个代码库.如果您正在使用源文件或静态库或动态库形式的分发,则可以更改/更新/修改您的库,而无需强制每个人重新编译.

  • "当你的库发生变化时,你强迫所有客户重新编译整个代码库" - 更糟糕的是,在实践中,你强迫他们在代码库发生变化时重新编译你的库. (4认同)
  • 虽然它确实使库很容易使用,并且在优化时帮助编译器. (4认同)
  • @GMan:取决于编译器.IIRC,GCC和MSVC现在都有链接时间代码生成工具,用于发布版本,这消除了大多数(如果不是全部)潜在的性能差异. (2认同)

Mat*_* M. 5

我会说,有可能在不使用许多语言功能的明确条件下:正如您所注意到的,static关键字的一些用法.

它可能需要一些技巧,但可以审查它们.

  1. 每当需要打破依赖关系循环时,您都需要保持标头/源的区别,即使这两个文件在实践中都是头文件.
  2. 必须在内联声明自由函数(非模板),编译器可能不会内联它们,但如果它们被声明,那么当客户端构建其库/可执行文件时,它们不会抱怨它们已被重新定义.
  3. 应使用函数/类方法中的本地静态属性模拟全局共享数据(全局变量和类静态属性).在实践中,就调用者而言,它几乎没有什么用处(只是补充()).请注意,在C++ 0x中,这成为一种受欢迎的方式,因为它保证是线程安全的,同时仍然保护初始化顺序惨败,直到那时......它不是线程安全的;)

尊重这3点,我相信你能够编写一个完全成熟的仅限标题的库(任何人都能看到我错过的其他内容吗?)

许多Boost库使用类似的技巧只是标题,即使他们的代码不是完全模板.例如Asio,非常有意识地使用标志提出替代方案(参见Asio 1.4.6的发行说明):

  • 只需要几个功能的客户无需担心构建/链接,他们只需抓住他们需要的东西
  • 那些依赖它或者想减少编译时间的客户可以构建自己的Asio库(使用自己的标志集),然后包含"轻量级"标题

通过这种方式(以图书馆开发人员的一些更多努力为代价),客户得到了他们的蛋糕并且也吃了它.我认为这是一个非常好的解决方案.

注意:我想知道static函数是否可以内联,我更喜欢自己使用匿名命名空间,所以从来没有真正研究过它......