由于模板是在头文件中定义的,编译器能够决定内联一个函数是否有利,这有意义吗?我听说现代编译器更清楚何时内联一个函数,并且忽略< code>inline提示。
编辑:我想接受两个答案,但这是不可能的。为了结束这个问题,我接受塞巴斯蒂安·马赫的回答,因为它获得了大多数选票,他在形式上是正确的,但正如我在评论中提到的,我认为小狗和组件10的答案也是正确的,从不同的角度来看。
问题出在 C 语义中,在内联关键字和内联
的情况下并不严格。塞巴斯蒂安·马赫(Sebastian Mach)说“如果你是认真的,就写内联”,但内联
的实际含义尚不清楚,因为它从原始含义演变为“阻止编译器对ODR违规行为婊子”的指令,正如Puppy所说。
这不是无关紧要的。不,并非每个函数模板默认都是inline
。标准甚至在显式特化([temp.expl.spec])中对此进行了明确说明
有以下内容:
a、 立方厘米
#include "tpl.h"
b.cc
#include "tpl.h"
tpl.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
也可能导致问题。
总之:对于非完全专用的函数模板,即至少携带一个未知类型的函数模板来说,您可以省略<code>inline</code>,并且不会收到错误,但它们仍然不是<code>内联</code>。对于完全专用化,即仅使用已知类型的专用化,不能省略它。
建议的经验法则:如果你的意思是内联
,只要保持一致。它让你少考虑是否要这样做,因为你可以。(这个经验法则符合Vandevoorde/Josuttis的C模板:完整指南)。
这无关紧要。所有模板都已经是inline
-更不用说截至2012年,inline
关键字的唯一用途是阻止编译器抱怨ODR违规。您绝对正确-您当前的编译器将知道自己内联什么,甚至可以在翻译单元之间这样做。
正如您所建议的,< code>inline是对编译器的一个提示,仅此而已。它可以选择忽略它,或者内联没有标记为内联的函数。
将<code>inline</code>与模板一起使用过去是一种(糟糕的)解决问题的方法,即每个编译单元将为同一模板类创建一个单独的对象,这将在链接时导致重复问题。通过使用<code>inline</code>(我认为),名称篡改会产生不同的效果,这会在链接时避免名称冲突,但代价是代码过于臃肿。
马歇尔·克莱恩(Marshall Cline)在这里比我解释得更好。