问题标签 [header-only]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 共享库中具有全局状态的 C++ 标头
我正在开发一个 C++ 库,理想情况下我会保留标头。
该库的特定部分需要全局状态。
假设这个例子需要一个全局的字符串向量。
static
我可以通过函数内的变量轻松实现这一点:
这对于使用该库的可执行文件非常有用。
现在由于某种原因,我还需要将该库打包到 macOS 框架中。
在该框架内,有可以访问此全局状态的已编译代码。
与该框架链接的可执行文件也是如此。
显然这不起作用,因为可执行文件和框架将对静态变量有单独的定义,从而使这个全局状态不那么全局。
有什么方法可以方便地完成此任务吗?
c++ - 通过宏内联和包含源之间的区别
我花了一些时间开发一个只有标题的库,并且偶然发现了一个十字路口。我在网上看到的任何地方,总是使用内联函数。但在 的示例中stb_image.h
,源代码只是写在标题的下半部分,由#ifdef STB_IMAGE_IMPLEMENTATION
类似这样的包围:
然后一个(最好是不是 main.cpp 的源)文件定义了一个具有相同名称的宏,并在之后包含标题,如下所示:
你为什么要使用一个而不是另一个?(或者更确切地说,为什么 stbi 会这样做?)
c++ - 在仅标头库中拆分大文件
我正在研究仅标头库的代码库。它包含这个Polygon
类,它的问题是它相当大:大约8000行。我试图打破这一点,但一直遇到麻烦。这个类和库的几个约束:
- 我不能随意将库更改为需要预编译的部分。这不适合我们当前的构建街道,人们强烈认为它只是标题。
- 该类对性能非常关键,它的分配和算法占我正在处理的应用程序总运行时间的 99% 以上。
- 有时这个类经常被构造(很多很多三角形),它会经常调用它的方法。因此,如果可能的话,我希望它没有虚拟表,并且除非编译器(GCC -O2)保证将其优化掉,否则不要为组合而追逐指针。
此类包含公共函数中对多边形的多项操作,例如area()
和contains(Point2)
。其中每一个都有针对各种用例的几种实现,主要是小多边形与大多边形,其中小多边形采用简单的单线程方法,但大多边形运行多线程或使用具有更好时间复杂度的算法。基本上是这样的(简化):
我的尝试是将这些操作中的每一个都放入一个单独的文件中。这似乎是关注点的逻辑分离,并使代码更具可读性。
到目前为止,我最好的尝试是这样的:
然而,这有一个主要缺点,即这些子文件不是完整的头文件。它们包含类的一部分,不应包含在Polygon
类之外。这不是灾难性的,但在一年后肯定很难理解。
我研究的替代方案:
- 混合。但是,mixin 无法访问基类中的数据。
- 自由浮动函数类似于 Boost 的做法。然而,这有几个问题: 自由浮动函数无法访问受保护的字段。当自由浮动函数需要它时,这些文件需要相互包含导致
Polygon
类是不完整的类型。需要提供指向多边形的指针(不确定这是否会得到优化?)。 - 提供实现类的模板参数。这最终类似于自由浮动函数,因为实现类需要访问 的受保护字段,
Polygon
当Polygon
实现需要它时它是不完整的,并且Polygon
仍然需要以某种方式提供给实现。 - 我曾想过通过继承来实现这一点,其中受保护的数据成员位于私有基类中。子类是详细的实现。然后会有一个包含所有公共函数的公共类,它们仍然可以调用详细实现。然而,这是典型的钻石问题,需要虚拟桌子。不过没有对此进行测试,因为这很难设置。
你认为最好的解决方案是什么?你知道我可以尝试的任何替代方案吗?
c++ - 仅标头环境中的 C++ 访问者模式
我目前在 C++ 的仅标头库中实现访问者模式时遇到了麻烦。
考虑以下应该支持访问者访问的类(为简单起见没有接口):
这是访问者的界面:
在 Header-Only 库中,Acceptor.hpp 必须包含 Visitor.hpp,Visitor.hpp 必须包含 Acceptor.hpp。由于两个标头都受Include-Guards保护,因此后一个标头将失败。使用前向声明也不能解决问题。
c++ - CMake 目标仅编译源文件
我正在使用 C++17 编写一个只有头文件的库。我想将它包含在一个“虚拟”源文件中:
目的是确保库正确包含其所有依赖项。我还想在其上运行静态分析器,并在启用尽可能多的编译器检查的情况下对其进行编译。
要创建一个正常的可执行目标,我需要添加该main()
函数,否则链接阶段将失败。我想我也可以创建一个静态库目标,它应该可以正常工作,尽管它会创建一个我不需要的工件。
还有其他选择吗?
c++ - 使用 C++ 仅头文件库时减少二进制文件大小和编译时间
我正在使用 tiny-dnn C++ 库作为基础创建一个 GDScript 包装器库。
问题是 tiny-dnn 只是标题,我必须将它包含在我的库的大部分 .cpp 文件中(毕竟,我正在创建一个包装器)。这导致编译时间为 1 分钟/文件和大约 300MB 的二进制文件。
作为“解决方案”,我决定将所有代码(20 个 .cpp 文件)放入一个大文件中,并且只包含一次 tiny-dnn。编译时间保持不变,但现在我只有一个文件,二进制大小减少到 ~50MB。根据这个实验,我猜在我包含它的时候,tiny-dnn 会被一遍又一遍地复制。
我可以使用上面的“解决方案”继续我的项目,但我仍然在质疑:有没有办法保持减少的二进制大小和减少的编译时间,仍然有单独的文件并且仍然使用 tiny-dnn?
顺便说一句,我正在使用 Linux 并使用 g++ 以及 SCons 进行编译。
c++ - 在已经使用仅标头库的项目中使用预编译标头?
我正在构建一个项目,我想制作一个预编译的头文件来提高性能。问题是我也在我的项目中使用 stbi_image 标头,这意味着我必须在我的项目中的所有 stbi 文件中包含我的标头,并确保其中没有重复的标头声明。
是否有另一种方法来包含 stbi 或绕过在这些文件中包含预编译头的方法?
c++ - Visual Studio 试图打开不再在项目中的源文件(致命错误 C1083)
问题很简单,真的。我的项目中包含了 imgui,我不再使用它。但是,每次我尝试编译时,VS 仍然会尝试打开它们。
我删除了所有包含并从我的项目中完全删除了文件。任何地方都没有提到它。我也没有将它作为外部库包含(它只是标题)。我已经没有想法了。
错误日志:
有没有办法解决这个问题?
c++ - C ++如何调用仅标头库
inline
我通过添加关键字学习了 C++17 处理仅标头库的方法:
运行上面的代码abc
按预期返回。
但是,如果我尝试使用 C++17 之前的样式,如下所示:
我得到了1
而不是预期的结果abc
。我想知道为什么以及如何解决它?
c++ - 在现代 CMake 中将接口库添加为 SYSTEM
我目前正在将我的 C++ 项目从简单地使用 Makefile 转换为使用 CMake。由于我不熟悉 CMake,我尽量避免学习“旧”CMake 并坚持“现代 CMake”最佳实践,例如此处描述的。
但是,我不知道如何包含一个简单的、仅包含标头的第三方库,而不会被有关该库的警告所困扰。
假设我有一个这样的项目结构:
说main.cpp
用途foo
:#include <foo.h>
问题是,我使用了一堆警告标志并foo.h
引入了一些我不关心的警告,因为我不是作者,这并不严重。
在经典的 Makefile 中,我只需在-isystem third-party-lib/foo
适当的地方编写并完成即可。
在 CMake 中,我通过include_directories(SYSTEM PRIVATE third-party-lib/foo)
顶级CMakeLists.txt
.
现在,根据上面的链接,我应该放手include_directories()
以避免隐藏的依赖关系,我认为这是一个好主意。我宁愿为每个实际需要foo
包含该库的目标指定并将其视为“不要在此处警告我”。据我了解,方法是:
foo
在顶层找到目标CMakeLists.txt
target_link_libraries(main PRIVATE foo)
左右src/CMakeLists.txt
我将如何实现这一点,即查找命令是什么,以及在哪里指定SYSTEM
属性?或有关如何解决此问题的任何其他建议?