将内联关键字与模板一起使用是否有意义?

时间:2012-05-10 14:03:20

标签: c++ templates inline

由于模板是在头文件中定义的,编译器能够确定内联函数是否有利,它是否有意义?我听说现代编译器知道何时内联函数并忽略inline提示。


编辑:我想接受这两个答案,但这是不可能的。为了解决这个问题,我接受了 phresnel 的回答,因为它收到了大多数选票并且他是正式的,但正如我在评论中提到的,我认为 Puppy 和< strong>组件10 的答案也是正确的,从不同的角度来看。

问题在于C ++语义,在inline关键字和内联的情况下并不严格。 phresnel 说“如果你的意思是写内联”,但inline的实际意义并不清楚,因为它从原来的含义演变为“阻止编制者对ODR违规行为嗤之以鼻”的指令“正如小狗所说的那样。

4 个答案:

答案 0 :(得分:80)

这不是无关紧要的。不,默认情况下,并非每个功能模板都是inline。该标准在明确专业化([temp.expl.spec])

中甚至是明确的

拥有以下内容:

a.cc

#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也可能导致问题。

总而言之:对于非完全专业化的功能模板,即带有至少一种未知类型的模板,您可以省略inline,但不会收到错误,但它们仍然不是inline。对于完全专业化,即仅使用已知类型的专业化,您不能省略它。

建议的经验法则:如果您的意思是写inline并保持一致。它会让你更少考虑是否因为你可以。 (这个经验法则符合Vandevoorde's/Josuttis's C++ Template: The Complete Guide)。

答案 1 :(得分:26)

这无关紧要。所有模板都已inline - 更不用说从2012年开始,inline关键字的唯一用途就是阻止编译器了解ODR违规行为。你绝对正确 - 你当前的编译器会知道它自己内嵌的内容,甚至可以在翻译单元之间这样做。

答案 2 :(得分:1)

如您所知,inline是对编译器的提示,仅此而已。它可以选择忽略它,或者实际上可以选择忽略内联的内联函数。

inline与模板一起使用是一种(糟糕的)解决问题的方法,即每个编译单元都会为同一模板类创建一个单独的对象,这会在链接时导致重复问题。通过使用inline(我认为),名称修改可以解决不同的问题,它会在链接时绕过名称冲突,但代价是膨胀的代码。

Marshall Cline explains it here比我更好。

答案 3 :(得分:0)

这是C ++标准所说的:

[dcl.inline/1]

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