BOOST_ERROR_CODE_HEADER_ONLY 没有宣传的效果

BOOST_ERROR_CODE_HEADER_ONLY does not have the advertised effect

在我的应用程序中,我包含 boost/system/error_code.hpp(提升 1.58)但不想 link 到 boost_system,而是有一个 header-only 解决方案。我通过定义 BOOST_ERROR_CODE_HEADER_ONLY 来阅读应该是可能的。但不幸的是,它没有按预期工作。我仍然收到 boost::system::system_category() 的 linker 错误。

我想知道这是否应该有效,如果有效如何。 boost中的代码header是:

# ifdef BOOST_ERROR_CODE_HEADER_ONLY
    inline const error_category &  system_category() BOOST_SYSTEM_NOEXCEPT;
    inline const error_category &  generic_category() BOOST_SYSTEM_NOEXCEPT;
#else
    BOOST_SYSTEM_DECL const error_category &  system_category() BOOST_SYSTEM_NOEXCEPT;
    BOOST_SYSTEM_DECL const error_category &  generic_category() BOOST_SYSTEM_NOEXCEPT;
#endif

正如您所见,没有为 system_category() 定义 body。如果没有 linking to a lib,这怎么能工作呢?

更新:

与此同时,我找到了定义该声明的 body 的位置(在 boost/system/error_code.hpp 文件中包含的 boost/system/detail/error_code.hpp 中。它仍然没有避免 link错误。我在 XCode (llvm C++11) 中工作,并且在目标设置中定义了 BOOST_ERROR_CODE_HEADER_ONLY,如果这很重要的话。

经过一些试验,我让它工作了。这里成功的关键是在包含 header 的任何其他代码之前包含 header boost/system/error_code.hpp,并且在包含之前直接定义 BOOST_ERROR_CODE_HEADER_ONLY 预处理器符号,在一个.cpp文件。必须将它包含在 cpp 文件中而不是,例如在预编译的 header(stdafx.h、*_prefix.h 等)中,因为它包含仅在 object 文件中有效的代码。在 project/target 级别定义 BOOST_ERROR_CODE_HEADER_ONLY 也可能有效,但由于您在整个 project/target 中只需要一次,因此在包含提升 [=24= 之前定义它更有意义] 第一次.

如果您遵循此规则,您也不会受到在多个 cpp 文件中包含相同 system_category() 代码时可能出现的重复符号问题的影响。

在发布模式下编译代码时,您可能仍然会遇到问题,因为编译器可能会自动删除包含的代码(如果未在该 cpp 文件中使用)。所以最好禁用它的优化。但是,由于您不希望常规代码使用它,因此专门为此创建一个自己的 cpp 文件是有意义的,包括并完全禁用对该文件的优化。这就是我最终的结局。