根据this answer提升和STL标头属于预编译头文件(MSVC世界中的stdafx.h
)。所以我更改了动态链接库项目的标题,并将所有STL / Boost标题移动到我项目的stdafx.h
中。
之前
#include <boost/smart_ptr.hpp>
namespace XXX
{
class CLASS_DECL_BK CExampleClass // CLASS_DECL_BK is just a standard dll import/export macro
{
private:
boost::scoped_ptr<Replica> m_replica;
}
}
后
namespace XXX
{
class CLASS_DECL_BK CExampleClass
{
private:
boost::scoped_ptr<Replica> m_replica;
}
}
现在我的优势是减少了编译时间,但是我的库的所有用户都遇到了构建错误(例如未知的boost :: scoped_ptr ...)因为缺少包含(这是现在转到我的stdafx.h
)。
什么可以解决这个困境?
我希望减少编译时间和编译错误后,包含我的头文件对于dll的任何用户都是不可接受的。
这有用吗?
感谢任何提示!
答案 0 :(得分:2)
您可以为此目的创建构建配置(Debug,Release,CheckDependencies)。更改此方法的一种简单方法是使用预处理器根据当前配置包含/排除包含。使用它,您可以使用调试或发布(包含更大的包含集)进行测试和构建,然后在分发之前构建所有配置。
澄清一下,条件包括MON_LIBRARY_VALIDATE_DEPENDENCIES
不会在库头文件或源代码中使用,只能在预编译头文件中使用:
// my pch:
#include <file1.hpp>
#include <file2.hpp>
// ...
#if !defined(MON_LIBRARY_VALIDATE_DEPENDENCIES)
#include <boost/stuff.hpp>
// ...
#endif
然后您将MON_LIBRARY_VALIDATE_DEPENDENCIES
附加到CheckDependencies配置中的预处理程序定义列表中。
关于警卫:如果你在正常情况下使用警卫, 应该不成问题 - 编译器使用优化来检测这些情况,这意味着如果它已经繁殖,他们可以避免在很多情况下打开文件正确包括和保护。实际上,在这个领域中试图超越编译器的尝试实际上可以减慢 down 来处理。我会说只是把它当作典型的,除非你的库/依赖关系很大并且你确实有明显的问题。
答案 1 :(得分:2)
当你将标题包括在库标题中并且只是将它们放入stdafx.h
时,你应该几乎相同的速度增加。
或者,您可以添加其他定义(批量external include guard)
// stdafx.h
#define MY_LIB_STD_HEADERS_ALREADY_INCLUDED
// library_file.h
#ifndef MY_LIB_STD_HEADERS_ALREADY_INCLUDED
#include <boost/smart_ptr.hpp>
...
#endif
但是如果你确定它有帮助,我只会这样做。只需要一个秒表并进行一些重新编辑。 (无需链接。)然后你会看到是否有任何不同。
我不确定在项目中添加所有升级标头某处是一个好主意。我会说shared_ptr
和朋友,boost/foreach
,也许是Boost.Format,...是个好主意,但我已经三思而后行了Boost.RegExp标题。 注意:我did not do any speed measurements,但我模糊地记得pch文件的大小和一些编译器打嗝的问题。我真的should do some tests。
同时检查相关的Boost Library是否提供转发标头以及是否应该包含它们。膨胀预编译的头文件可能会有它的缺点。
答案 2 :(得分:1)
让你的编译单元自包含(让它们包括他们使用的所有东西)是非常可取的。这将防止其他不使用预编译头文件的编译错误,并且正如您所假设的那样,标头保护将使这些额外包含的成本保持最小。
这也有一个理想的副作用,一看标题就会告诉用户单位中正在使用哪些其他标题,以及在没有任何模糊的情况下编译单个单位的选项。