4

根据这个答案boost 和 STL 头文件属于预编译的头文件stdafx.h在 MSVC 世界中)。因此,我更改了动态链接库项目的标头,并将所有 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 的任何用户都是不可接受的。

这有帮助吗?

  • 保留所有包含指令,但在我的“stdafx.h”中复制它们?由于 stdafx.h 总是首先包含在我项目的任何 cpp 文件中,所以我应该没问题,并且用户不会收到任何错误。或者,如果在一个翻译单元中出现多个包含相同标题的内容(有标题保护),我是否会失去速度优势?

感谢您的任何提示!

4

3 回答 3

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 配置中的预处理器定义列表。

关于守卫:如果您在正常情况下使用守卫,这应该不是问题 - 编译器使用优化来检测这些情况,这意味着如果文件被多次包含并正确保护,它们可以避免在许多情况下打开文件。事实上,在这个领域试图超越编译器实际上会减慢处理速度。我会说除非您的库/依赖项很大并且您确实有明显的问题,否则请将其保留为典型。

于 2011-09-02T07:58:12.230 回答
2

当您将header -includes 保留在库头文件中并另外将它们放入stdafx.h.

或者,您可以添加一个额外的定义(一个批量外部包含警卫

// 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

但我只会在你确定它有帮助的情况下这样做。只需拿一个秒表并运行一些重新编译。(无需链接。)然后你会看到是否有任何区别。

在旁边

我不确定在项目的某个地方添加所有需要的 boost 标头是否是个好主意。我想说和朋友们,也许 Boost.Format, ... 是个好主意,但我已经为 Boost.RegExp 标头三思而后行。注意:我没有进行任何速度测量,但我依稀记得 pch 文件的大小和一些编译器打嗝的问题。我真的应该做一些测试shared_ptrboost/foreach

Also check if the Boost Library in question provides forwarding headers and whether you should include them instead. Bloating the precompiled header file can have it's downsides.

于 2011-09-02T08:01:46.740 回答
1

使您的编译单元自包含(让它们包含它们使用的所有内容)是非常可取的。这将防止其他不使用预编译头文件的编译错误,并且正如您所假设的,头文件保护将使这些额外包含的成本最小化。

这也将具有理想的副作用,即浏览标题将告诉用户单元中正在使用哪些其他标题,以及在没有任何模糊的情况下编译单个单元的选项。

于 2011-09-02T08:00:23.463 回答