- 头文件中定义的任何函数都会自动内联吗?
- 如果我在一个类中声明一个函数并在外部使用关键字 inline 给出定义,这个函数会是内联的吗?如果是的话,为什么这不违反内联函数在声明时应该被赋予主体的法律?
3 回答
在类定义中定义的任何函数都是内联的。任何标记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
如果所有这些代码都在一个标题中,并且该标题用于多个翻译单元,您将收到C::h
包含多个定义的投诉。C::f
并且C::g
没关系,因为它们是内联的。这就是当今的主要作用inline
:允许在多个地方定义相同的函数(只要定义是“相同的”)。
头文件中定义的任何函数都会自动内联吗?
不,您应该手动将在类主体之外定义的任何函数内联。否则,您很可能会违反ODR (如果在多个翻译单元中包含标题)。
ISO C++11
3.2 一定义规则
1:任何翻译单元不得包含一个以上的任何变量、函数、类类型、枚举类型或模板的定义。
[...]
4:每个程序都应包含该程序中odr使用的每个非内联函数或变量的准确定义;无需诊断。定义可以显式出现在程序中,可以在标准或用户定义库中找到,或者(在适当时)隐式定义(参见 12.1、12.4 和 12.8)。内联函数应在使用它的每个翻译单元中定义。
如果我在一个类中声明一个函数并使用关键字 inline 在外部给出定义,这个函数会是内联的吗?如果是的话,为什么这不违反内联函数在声明时应该被赋予主体的法律?
有几种方法可以内联成员函数:
一、根据7.1.2/3:
在类定义中定义的函数是内联函数。inline 说明符不应出现在块作用域函数声明中。90 如果在友元声明中使用了 inline 说明符,则该声明应为定义,或者该函数应先前已被声明为内联。
struct First
{
void first(){}
};
二、三、四,根据9.3/3:
内联成员函数(无论是静态的还是非静态的)也可以在其类定义之外定义,只要它在类定义中的声明或其在类定义之外的定义将该函数声明为 inline。[注意:命名空间范围内的类的成员函数具有外部链接。本地类 (9.8) 的成员函数没有链接。见 3.5。——尾注]
struct STF
{
void second();
inline void third();
inline void fourth();
};
inline void STF::second(){}
void STF::third(){}
inline void STF::fourth(){}
inline
是一个“提示”,只要编译器不必遵守它。它可以使您未标记为内联的内容内联,并且不必内联您标记为内联的内容。
我的意思是你不应该依赖它。许多人建议您甚至不要使用它,因为它具有误导性。大多数现代编译器完全忽略它。
唯一的实际用途是允许您将静态实现放入标题中。这是否是一件好事是有争议的。