在模板中使用内联关键字有意义吗?

因为模板是在头中定义的,而编译器能够确定内联函数是否有利,所以这样做有意义吗?我听说现代编译器更清楚什么时候内联函数,而忽略了 inline提示。


我想接受这两个答案,但这是不可能的。为了结束这个问题,我接受 塞巴斯蒂安 · 马赫的答案,因为它收到了大多数的投票,他是正确的,但是正如我在评论中提到的,我认为 小狗第十部分的答案也是正确的,从不同的角度来看。

问题在于 C + + 语义,在 inline关键字和内联的情况下,C + + 语义并不严格。塞巴斯蒂安 · 马赫说“如果你是认真的,就写内联”,但是 inline的实际含义并不清楚,因为它从最初的含义演变成了一个指令,如 小狗所说,“停止编译器抱怨 ODR 违规”。

80129 次浏览

这无关紧要。所有的模板都已经是 inline了——更不用说到2012年为止,inline关键字的唯一用途就是阻止编译器抱怨 ODR 违规。您是绝对正确的-您当前生成的编译器将知道自己内联什么,甚至可能在翻译单元之间也可以做到这一点。

正如您所建议的,inline只是对编译器的一个提示,仅此而已。它可以选择忽略它,也可以选择忽略未标记为 inline 的内联函数。

使用带有模板的 inline曾经是一种(糟糕的)解决问题的方法,即每个编译单元将为相同的模板类创建一个单独的对象,这将在链接时导致重复问题。通过使用 inline(我认为) ,名称错位会产生不同的结果,在链接时避免了名称冲突,但代价是代码过于臃肿。

马歇尔 · 克莱因 这里有解释比我好多了。

这不是无关紧要的。不,并非每个函数模板都是 inline默认值。这个标准甚至在 明确的专业化([ tem.exp.spec ])中是明确的

具备以下条件:

空调

#include "tpl.h"

密件抄送

#include "tpl.h"

H (取自显式专门化) :

#ifndef TPL_H
#define TPL_H
template<class T> void f(T) {}
template<class T> inline T g(T) {}


template<> inline void f<>(int) {} // OK: inline
template<> int g<>(int) {} // error: not inline
#endif

编译这个,就这样:

g++ a.cc b.cc
/tmp/ccfWLeDX.o: In function `int g<int>(int)':
inlinexx2.cc:(.text+0x0): multiple definition of `int g<int>(int)'
/tmp/ccUa4K20.o:inlinexx.cc:(.text+0x0): first defined here
collect2: ld returned 1 exit status

在进行显式实例化时不声明 inline也可能导致问题。

因此,总结 : 对于非完全专用的函数模板,即那些至少包含一种未知类型的模板,您可以省略 inline,并且不会收到错误,但它们仍然不是 inline。对于完整的专门化,即只使用已知类型的专门化,您不能忽略它。

建议的经验法则 : 如果你是认真的,就写 inline,并且保持一致。这会让你更少地考虑是否要这么做,因为你可以这么做。(经验法则符合 Vandevoorde/Josuttis’s < em > C + + 模板: 完整指南)。

C + + 标准是这么说的:

[ dcl.inline/1]

内联说明符只应用于变量或函数的声明。