函数何时应该内联?

When should a function be inline or not?

本文关键字:何时应 函数      更新时间:2023-10-16

假设我在头文件中声明了以下类,并swap了一个友元函数:

// header.h
class myClass
{
friend void swap(myClass &, myClass &);
public:
myClass(int ii = 0) : i(ii) {}
private:
int i;
};

现在我想定义swap.如果我稍后在同一个头文件中定义它,就像这样,

inline void swap(myClass &a, myClass &b)
{
using std::swap;
swap(a.i, b.i);
}

一切都很好。但是,如果我删除inline说明符,则会出现错误。

现在假设我想在单独的实现文件中定义swap。如果我这样定义它,

// impl.cc
#include "header.h"
void swap(myClass &a, myClass &b)
{
using std::swap;
swap(a.i, b.i);
}

一切都很好。但是现在,如果我添加inline说明符,则会出现错误。

为什么一个版本需要inline而另一个版本不能有?

来自C++标准(9.1.6 内联说明符)

6如果内联函数或变量在翻译单元中使用, 从该译文的末尾可以得出它的定义 单位,并且在每个这样的定义中应具有完全相同的定义 翻译单元(6.2)。[注意:对内联函数的调用或使用 的内联变量在其定义之前可能会遇到 显示在翻译单元中。—尾注] 如果定义 函数或变量在其第一个点上可访问 声明为内联,程序格式不正确。如果函数或 具有外部或模块链接的变量在 One 中内联声明 翻译单元,所有翻译单元中应有一个可访问的内联声明 声明它的翻译单位;无需诊断。 具有外部或模块链接的内联函数或变量应 在所有翻译单元中具有相同的地址。[注意:静态本地 内联函数中的变量始终具有外部或模块链接 指同一对象。在内联主体中定义的类型 带有外部或模块链接的功能在每个 翻译股。—尾注]

因此,要么在标头中将 friend 函数声明为内联函数,以便可以在使用它的每个翻译单元中访问其定义。或者该函数是非内联函数,其定义应放置在一个编译单元中以满足一个定义规则。