由于模板是在头文件中定义的,编译器能够确定内联函数是否有利,它是否有意义?我听说现代编译器知道何时内联函数并忽略inline
提示。
编辑:我想接受这两个答案,但这是不可能的。为了解决这个问题,我接受了 phresnel 的回答,因为它收到了大多数选票并且他是正式的,但正如我在评论中提到的,我认为 Puppy 和< strong>组件10 的答案也是正确的,从不同的角度来看。
问题在于C ++语义,在inline
关键字和内联的情况下并不严格。 phresnel 说“如果你的意思是写内联”,但inline
的实际意义并不清楚,因为它从原来的含义演变为“阻止编制者对ODR违规行为嗤之以鼻”的指令“正如小狗所说的那样。
答案 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)