内联函数和类和头文件

Wei*_*Sun 3 c++ inline class one-definition-rule

  1. 头文件中定义的任何函数是否会自动内联?
  2. 如果我在类中声明一个函数并使用关键字内联给出定义,那么这个函数是否内联?如果是这样,为什么这不违反法律规定,内联职能应在宣布时给予机构?

Pet*_*ker 7

在类定义中定义的任何函数都是内联的.标记的任何功能inline也是内联的.

class C {
    int f() { return 3; } // inline
    int g();
    int h();
}


inline int C::g() { return 4; } // inline
int C::h() { return 5; } // not inline
Run Code Online (Sandbox Code Playgroud)

如果所有这些代码都在标题中,并且该标题用于多个翻译单元,那么您将获得C::h具有多个定义的投诉.C::f并且C::g没关系,因为它们是内联的.这是当今的主要角色inline:允许在多个地方定义相同的功能(假设定义"相同").


Evg*_*yuk 5

\n

头文件中定义的任何函数都会自动内联吗?

\n
\n

不,您应该手动将类体外部定义的任何函数内联。否则,您很可能会遇到ODR违规(如果在多个翻译单元中包含标头)。

\n

ISO C++11

\n
\n

3.2 单一定义规则

\n

1:任何翻译单元都不得包含任何变量、函数、类类型、枚举类型或模板的多个定义。

\n

[...]

\n

4:每个程序都应包含该程序中使用的每个非内联函数或变量的精确定义;无需诊断。该定义可以显式地出现在程序中,可以在标准或用户定义的库中找到,或者(在适当的情况下)它是隐式定义的(参见12.1、12.4和12.8)。内联函数应在使用 odr 的每个翻译单元中定义。

\n
\n
\n
\n

如果我在类中声明一个函数并使用关键字 inline 在外部给出定义,这个函数会是内联的吗?如果是,为什么这不违反内联函数应在声明时赋予主体的法律?

\n
\n

有几种方法可以内联成员函数:

\n

首先,根据7.1.2/3:

\n
\n

在类定义中定义的函数是内联函数。内联说明符不得出现在块作用域函数声明中。90 如果在友元声明中使用内联说明符,则该声明应是定义,或者该函数之前应已声明为内联。

\n
\n
struct First\n{\n    void first(){}\n};\n
Run Code Online (Sandbox Code Playgroud)\n

第二、第三和第四,根据 9.3/3:

\n
\n

成员函数(无论是静态还是非静态)也可以在其类定义之外定义,前提是其在类定义中的声明或其在类定义之外的定义将该函数声明为 inline。[ 注意:命名空间范围内的类的成员函数具有外部链接。本地类(9.8)的成员函数没有链接。见 3.5。\xe2\x80\x94结束注]

\n
\n
struct STF\n{\n    void second();\n    inline void third();\n    inline void fourth();\n};\n\ninline void STF::second(){}\nvoid STF::third(){}\ninline void STF::fourth(){}\n
Run Code Online (Sandbox Code Playgroud)\n

  • 问题只是同一事物的多个定义。这与 ODR 无关,ODR 要求当允许多个定义时,它们必须相同。此外,它不仅仅是非成员函数,还包括未在类定义中定义的**任何**函数。 (2认同)
  • 真的。如果您有两个同名的非内联定义,则会出现错误;一直如此,永远如此。在这个问题的上下文中,ODR 表示,当同一函数有两个定义都标记为“内联”时,它们必须是“相同的”。所以 `inline int f() { return 3; } 内联 int f() { 返回 4; }` 违反了 ODR。`int f() { 返回 3; } int f() { 返回 3; }` 只是同一事物的两个定义,并且是一个错误。 (2认同)