简体   繁体   English

仅限标头库和多个定义错误

[英]Header-only libraries and multiple definition errors

I want to write a library that to use, you only need to include one header file. 我想写一个要使用的库,你只需要包含一个头文件。 However, if you have multiple source files and include the header in both, you'll get multiple definition errors, because the library is both declared and defined in the header. 但是,如果您有多个源文件并在两者中都包含标头,则会出现多个定义错误,因为该标头都是在标头中声明和定义的。 I have seen header-only libraries, in Boost I think. 我认为在Boost中我看过只有头文件的库。 How did they do that? 他们是怎么做到的?

Declare your functions inline , and put them in a namespace so you don't collide: 声明函数inline ,并将它们放在命名空间中,这样就不会发生冲突:

namespace fancy_schmancy
{
  inline void my_fn()
  {
    // magic happens
  }
};

The main reason why Boost is largely header-only is because it's heavily template oriented. Boost主要仅仅是标题的主要原因是因为它主要是面向模板的。 Templates generally get a pass from the one definition rule. 模板通常从一个定义规则获得传递。 In fact to effectively use templates, you must have the definition visible in any translation unit that uses the template. 实际上,为了有效地使用模板,您必须在使用该模板的任何翻译单元中显示该定义。

Another way around the one definition rule (ODR) is to use inline functions. 围绕一个定义规则(ODR)的另一种方法是使用inline函数。 Actually, getting a free-pass from the ODR is what inline really does - the fact that it might inline the function is really more of an optional side-effect. 实际上,从ODR获得一个免费通行证就是inline实际上做的事情 - 事实上它可能内联函数实际上更多是一个可选的副作用。

A final option (but probably not as good) is to make your functions static. 最后一个选项(但可能不太好)是让你的函数保持静态。 This may lead to code bloat if the linker isn't able to figure out that all those function instances are really the same. 如果链接器无法确定所有这些函数实例是否真的相同,则可能导致代码膨胀。 But I mention it for completeness. 但我提到它是完整的。 Note that compilers will often inline static functions even if they aren't marked as inline . 请注意,编译器通常会内联static函数,即使它们未标记为inline函数。

Boost uses header-only libraries a lot because like the STL, it's mostly built using class and function templates, which are almost always header-only. Boost使用了只有头文件库,因为像STL一样,它主要是使用类和函数模板构建的,它们几乎总是只有头文件。

If you are not writing templates I would avoid including code in your header files - it's more trouble than it's worth. 如果你不编写模板,我会避免在你的头文件中包含代码 - 这比它的价值更麻烦。 Make this a plain old static library. 使它成为一个普通的旧静态库。

There are many truly header-only Boost libraries, but they tend to be very simple (and/or only templates). 有许多真正的只有标头的Boost库,但它们往往非常简单(和/或只有模板)。 The bigger libraries accomplish the same effect through some trickery: they have "automatic linking" (you'll see this term used here ). 较大的库通过一些技巧实现相同的效果:它们具有“自动链接”(您将在此处看到这个术语)。 They essentially have a bunch of preprocessor directives in the headers that figure out the appropriate lib file for your platform and use a #pragma to instruct the linker to link it in. So you don't have to explicitly link it, but it is still being linked. 它们在头文件中基本上有一堆预处理程序指令,用于为您的平台找出适当的lib文件,并使用#pragma指示链接器将其链接。因此您不必显式链接它,但它仍然是被联系起来。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM