你和这里提供小函数建议的人们,是用传统的方式看待inline
。
inline
曾经代表“我希望这段代码可以快速执行,所以每当我调用此函数时,我希望你将其就地扩展,以避免函数调用的开销。”
这是一个非常好的优化。实际上,编译器甚至会积极地这样做,即使您没有指定inline
。
编译器也可以选择不扩展您的inline
函数。因此,您真的不必担心它会如何影响性能,因为如果您愚蠢地使用它,编译器可以并且会忽略inline
。
事实上,现在的编译器几乎总是忽略您对inline
的使用,并且只会执行它们认为最好的操作。
既然如此,为什么人们还要使用inline
?
现在只有一种情况需要使用inline
,那就是解决“单一定义规则”(ODR)。
在C/C++中,您只允许定义一个函数。如果您这样做:
int foo() { }
int foo() { }
编译器会抱怨你定义了同一个函数两次。这看起来像个愚蠢的例子,但在使用 #include 时很容易犯这样的错误——如果你在头文件中定义了函数,并且两次 #include 相同的头文件,那么就会出现这种情况。幸运的是,inline 还有另一个用途,它仍然有效:如果你将函数标记为 inline,则强制编译器消除 ODR 问题,使得可以在头文件中定义函数。换句话说,现在 inline 的意思是“我想在头文件中定义这个函数”。从这个角度看,当你将函数移动到 cpp 文件中时,应该清除 inline。有趣的是,有几个地方会隐式地使函数成为内联函数,其中之一是类成员函数。
struct Foo {
void bar() { }
};
我看到有人将函数标记为inline
,但这是完全多余的。编译器会自动这样做;不需要担心ODR,也没有性能可提高。
另一个地方是在模板中。由于模板必须在头文件中定义,它们免于ODR,因此将其标记为inline
是多余的。