函数什么时候应该内联或不内联?

When should a function be inline or not?

假设我在头文件中声明了以下 class,带有友元函数 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 If an inline function or variable is odr-used in a translation unit, a definition of it shall be reachable from the end of that translation unit, and it shall have exactly the same definition in every such translation unit (6.2). [Note: A call to the inline function or a use of the inline variable may be encountered before its definition appears in the translation unit. —end note] If a definition of a function or variable is reachable at the point of its first declaration as inline, the program is ill-formed. If a function or variable with external or module linkage is declared inline in one translation unit, there shall be a reachable inline declaration in all translation units in which it is declared; no diagnostic is required. An inline function or variable with external or module linkage shall have the same address in all translation units. [Note: A static local variable in an inline function with external or module linkage always refers to the same object. A type defined within the body of an inline function with external or module linkage is the same type in every translation unit. —end note]

因此,要么在 header 中将友元函数声明为内联函数,这样它的定义在使用它的每个翻译单元中都可以访问。或者该函数是一个non-inline函数,它的定义应该放在一个编译单元中以满足One Definition Rule。