函数与变量的inline说明符
- 当在函数的decl-specifier-seq中使用时,inline说明符会将函数声明为内联函数。
- 当在具有静态存储期的变量的decl-specifier-seq中使用时,inline说明符会将变量声明为内联变量。
隐式内联函数(不用inline说明符本身就是inline的)
- 在class/struct/union定义内部,无论是成员函数还是非成员友元函数都是隐式内联函数
- 在一个函数的首次声明中就被声明为constexpr,这个函数为内联函数
什么是内联?
inline的本意是作为一种给optimizer的indicator,告诉优化器优先采用函数的inline substitution而不是调用,即并不执行将控制转移到函数体内的函数调用 CPU 指令,而是代之以执行函数体的一份副本而无需生成调用。这会避免函数调用的开销(传递实参及返回结果),但它可能导致更大的可执行文件,因为函数体必须被复制多次。
什么时候用内联?
- 被多个源文件包含的函数必须是内联的
- 拥有外部链接的被多个源文件包含的变量必须是内联的
Header “example.h”
#include <atomic>
inline int sum(int a,int b)
{
return a+b;
}
inline std::atomic<int> couter(0);
Source file #1
int a()
{
counter++;
return sum(1,2);
}
Source file #2
int b()
{
counter++;
return sum(3,4);
}
inline命名空间定义
内联命名空间是指在命名空间的original-namespace-definition中用了inline关键字的命名空间。
内联命名空间的成员都被当做如同它们是外围命名空间(与该命名空间最近的一层命名空间)的成员一样。
namespace Lib
{
inline namespace Lib_1
{
template<typename T> class A;// 类模板声明
}
template<typename T> void g(T) {}// 函数模板
}
struct MyClass {}; // 结构体类型
namespace Lib
{
template<> class A<MyClass> {}// 模板实例化,内联命名空间
// Lib_1中的成员视为enclosing namespace外围命名空间Lib的
// 一部分,可以直接通过Lib访问
}
int main()
{
Lib::A<Myclass> a;
g(a); // Lib is an associated namespace of A
}