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

Epr*_*pro 14 c++ header multiple-definition-error

我想写一个要使用的库,你只需要包含一个头文件.但是,如果您有多个源文件并在两者中都包含标头,则会出现多个定义错误,因为该标头都是在标头中声明和定义的.我认为在Boost中我看过只有头文件的库.他们是怎么做到的?

Joh*_*ing 28

声明你的函数inline,并将它们放在命名空间中,这样就不会发生碰撞:

namespace fancy_schmancy
{
  inline void my_fn()
  {
    // magic happens
  }
};
Run Code Online (Sandbox Code Playgroud)

  • 忽略你的教授.他们不会为了生活而编写代码."只有简短的函数应该被内联"是一个经验法则,但是有很多例外以及许多其他更重要的原因,为什么你应该或者应该*不*内联函数以使经验法则几乎无用. (5认同)
  • @Arun:编译器不需要内联所有`inline`函数,如果你通过函数指针调用它也不能.`inline`关键字提示内联可能很好,但更重要的是它是一个链接修饰符.这是一个不幸的误称.无论如何,不​​要担心你的编译器做任何愚蠢的事情. (2认同)
  • @Arun:不*不*让整个项目`inline`.`inline`是一个服务于某个目的的工具(实际上是一些目的).在这种情况下,在大多数情况下,我们使用`inline`的原因是为了满足ODR - 而不是作为性能调整.了解该工具,它适用的位置及其效果,然后在适当的地方使用它. (2认同)

Mic*_*urr 6

Boost主要仅仅是标题的主要原因是因为它主要是面向模板的.模板通常从一个定义规则获得传递.实际上,为了有效地使用模板,您必须在使用该模板的任何翻译单元中显示该定义.

围绕一个定义规则(ODR)的另一种方法是使用inline函数.实际上,从ODR获得免费通行证inline确实是这样 - 事实上它可能内联函数实际上更多是一个可选的副作用.

最后一个选项(但可能不太好)是让你的函数保持静态.如果链接器无法确定所有这些函数实例是否真的相同,则可能导致代码膨胀.但我提到它是完整的.请注意,编译器通常会内联static函数,即使它们没有标记为inline.