C++ 如何在标题库中定义(非方法)函数

C++ 如何在标题库中定义(非方法)函数,c++,boost,static,header,warnings,C++,Boost,Static,Header,Warnings,在编写头库(如)时,是否可以定义自由浮动(非方法)函数,而不会(1)使生成的二进制文件膨胀(2)产生“未使用”警告 当我在由多个源文件包含的头文件中定义一个函数时,这些源文件又被链接到同一个二进制文件中,链接器会抱怨重新定义。解决这个问题的一种方法是使函数保持静态,但这会在每个翻译单元中复制代码(顺便说一句,链接器能否安全地解除这些功能的重复?)。此外,这会触发编译器关于函数未使用的警告 我试图在Boost中寻找一个自由浮动函数的例子,但我找不到。包含类(或模板)中所有内容的技巧是什么?您可以使

在编写头库(如)时,是否可以定义自由浮动(非方法)函数,而不会(1)使生成的二进制文件膨胀(2)产生“未使用”警告

当我在由多个源文件包含的头文件中定义一个函数时,这些源文件又被链接到同一个二进制文件中,链接器会抱怨重新定义。解决这个问题的一种方法是使函数保持静态,但这会在每个翻译单元中复制代码(顺便说一句,链接器能否安全地解除这些功能的重复?)。此外,这会触发编译器关于函数未使用的警告


我试图在Boost中寻找一个自由浮动函数的例子,但我找不到。包含类(或模板)中所有内容的技巧是什么?

您可以使用
内联
关键字:

inline void wont_give_linker_errors(void)
{
    // ...
}

如果您确实想定义函数(而不是声明函数),则需要使用
inline
来防止链接器错误


否则,您可以在头文件中声明函数,并在源文件中单独提供其实现。

除了前面提到的
内联
,大多数编译器模板都必须在头文件中定义(所有编译器都允许这样做)。由于boost主要是模板,这就解释了为什么它几乎是所有的头文件

有人建议使用
内联
,但这违反了问题的第一部分,即在每次调用函数时将完整定义插入到代码中时会使代码膨胀。因此,你的整个问题的答案是“不”

如果您将它们标记为
static
,那么它们仍然在每个源文件中定义,正如您正确指出的那样,但是只定义了一次,因此如果代码大小是唯一的问题,那么这是一个比
inline
更好的选择。我不知道链接器是否能够或被允许发现重复项并合并它们。我想不是

编辑


为了澄清我是否支持使用
static
和/或在头文件中定义函数的概念,请放心,我不支持。这只是针对头文件中定义的标记为
内联
静态
的函数之间的差异的技术响应。没别的了。

呃。。。你的问题的答案是:不要。您只是不在头文件中定义函数,除非它们是内联的

“static”函数也可以在标题中定义,但它仅适用于非常特殊的用途。使用“静态”来解决多定义问题完全是胡说八道

同样,头文件用于非定义函数声明。你到底为什么要在那里定义函数


你说你在写“标题库”。什么是“标题库”?请注意,Boost在头文件中定义了它的“函数”,因为它们的“函数”不是真正的函数,而是函数模板。函数模板必须在头文件中定义(嗯,几乎是这样)。如果不是这样的话,Boost就不会像在头文件中定义任何东西那样奇怪了。

你为什么要这样做呢?顺便说一句,链接器可以安全地解除这些复制吗?你可能有更好的机会使用内联。有一些特定于实现的功能可以在限制阶段解决这个问题。类似于MS实现中的
\uuuu declspec(selectany)
,以及GCC.Er中的
\uuuu属性(弱))
,模板:)尽管如此,这一点还是很好。我在回答中提到了使用
静态
的技术性质,但没有提到它的正确性。如果OP是在定义模板,他一开始就不会有多个定义问题。另外,这里有一个术语上的区别,我一直试图观察到:函数模板不是函数。是的,我知道如果他使用模板,他不会有那个问题。这和面包的价格有什么关系?我想我不得不相信你的话,你用“函数”来指代非模板函数,显然你的编辑是在我的评论之后出现的。很抱歉给你投票。也许我误解了你的评论(我仍然不明白是什么冒犯了你)。但即使我的编辑出现在你的评论之后,我还是在我提交编辑后才看到你的评论(即,你提交了评论,而我正忙着编辑)。当然,你只能相信我的话。
inline
有两个作用:第一,防止多个定义出错。其次,它向编译器提示此函数可以内联。实际上,编译器不内联大函数(除非它是唯一的内联函数),不是相反吗?那些触发“未使用”警告的正是静态函数吗?(静态不是意味着每个包含文件都有自己的函数版本吗?因为它是“定制的”,如果他们都在某个地方使用它,那就太好了。)@peterchen:我知道这是一个提示,所以我在描述一个最坏的情况,我没有弄清楚。@UncleBens:我不确定你问的是谁?使用
static
很可能会给出未使用的警告,当然OP说这对他是有好处的。我当然没有说任何反驳的话。@Troubadour:我的意思是,你提到了要求1),但建议了一些几乎肯定会不符合要求2的东西。另外,静态不意味着相同的函数将被多次生成,从而使exe变大吗?还有,是什么让您认为编译器不能选择内联(或不内联)静态函数,只要它看到实现?(据我所见,
inline
的目的是让您可以在头文件中定义函数,没有头文件,编译器只能选择不内联。)当然,使用“inline”会增加函数内联的可能性,这可能会导致代码膨胀