由于之前有系统的学过 C 语言,现在在学习 C++ 的过程中采用的是对比学习方式,C 语言中没有涉及到的会补充记录一下。
内联函数(Inline Function)是 C++ 中一种特殊的函数,其定义直接在每个调用点展开,这意味着编译器会尝试将函数调用替换为函数本身的代码,这样可以减少函数调用的开销,尤其是在小型函数中。
特点
使用方法
通过在函数声明前添加关键字 inline 来指示编译器该函数适合内联
inline int max(int x, int y)
{
return x > y ? x : y;
}
#include <iostream>
inline int add(int a, int b)
{
return a + b;
}
int main()
{
int result = add(5,3);// 编译器可能会将此替换为:int result = 5 + 3;
std::cout << "Result:" << result << std::endl;
return 0;
}
// 在这个示例中,函数 add 被定义为内联函数。当它被调用时,编译器可能会将函数调用替换为函数体内的代码。
注意事项
内联函数是一种用于优化程序性能的工具,但需要合理使用,以确保代码的可维护性和性能的平衡。
Lambda 表达式是 C++11引入的一种匿名函数的方式,它允许你在需要函数的地方内联地定义函数,而无需单独命名函数。
Lambda表达式的基本语法如下:
[capture clause](parameters) -> return_type
{
// 函数体
// 可以使用捕获列表中的变量
return expression; // 可选返回语句
}
Lambda 表达式由以下部分组成:
Lambda表达式最简单的案例是在需要一个小型函数或临时函数时直接便用它,以下是一个非常简单的例子,其中使用Lambda 表达式来定义一个加法操作,并立即使用它来计算两个数的和。
// 使用 Lambda 表达式进行加法
#include <iostream>
int main()
{
int x = 50;
int y = 20;
auto add = [](int a, int b) -> int{
return a + b;
};
int ret = add(x, y);
std::cout << ret;
return 0;
}
// 使用匿名 Lambda 函数来返回两个数中较大的数
#include <iostream>
using namespace std;
//bool compare(int a, int b)
//{
// return a > b;
//}
int getMax(int a, int b, bool (*pcompare)(int a, int b))
{
if(pcompare(a, b))
{
return a;
}else{
return b;
}
}
int main()
{
int x = 30;
int y = 20;
// int max = getMax(x, y, compare);
// 下面改写为 Lambda 表达式
int max = getMax(x, y, [](int a, int b) -> bool{
return a > b;
});
cout << max << endl;
return 0;
}
#include <iostream>
using namespace std;
int main()
{
int x = 10;
int y = 20;
auto add = [x, y]() -> int{
// x++;
// x = 15; 这种方式捕获,不能修改变量值,只能用(可读)
return x + y;
};
int ret = add();
cout << ret << endl;
int z = 5;
auto mul = [=]() -> int{
// x++;
// x = 15; 这种方式捕获所有变量,不需要去列表中写明,不能修改变量值,只能用(可读)
return x * y * z;
};
ret = mul();
cout << ret << endl;
// 用引用的方式捕获,引用类似指针,进行地址访问
auto modifyMul = [&]() -> int{
// x++;
x = 15; // 引用的方式进行所有变量的捕获,可读可写(即可以修改变量的值)
return x * y * z;
};
ret = modifyMul();
cout << ret << endl;
cout << "x = " << x << endl;
return 0;
}
/*
第一个 Lambda 表达式 sum 按值捕获了 x 和 y (即它们的副本)。这意味 sum 内的 x 和 y 是在 Lambda 定义时的值的拷贝。
第二个 Lambda 表达式 mul使用 [=] 捕获列表,这表示它按值捕获所有外部变量。
第三个 Lambda 表达式 modifyMul使用 [&] 捕获列表,这表示它按引用捕获所有外部变量,因此,它可以修改 x 和 y 的原始值。
*/
这个示例展示了如何使用不同类型的捕获列表(按值和按引用)来控制 Lambda 表达式对外部变量的访问和修改。按值捕获是安全的,但不允许修改原始变量,而按引用捕获允许修改原始变量,但需要注意引用的有效性和生命周期问题。
特性 | Lambda 函数 | 内联函数 |
---|---|---|
定义 | 一种匿名函数,通常用于定义在需要他们的地方 | 一种常规函数,通过 inline 关键字定义 |
用途 | 提供一种快捷方式来定义临时的、小型的函数 | 用于优化小型函数,减少函数调用的开销 |
语法 | 使用 [capture] ( params ) { body }的形式定义 | 使用常规函数定义语法,但在前边加上 inline 关键字 |
生命周期 | 在定义他们的作用域内有效 | 在整个程序执行期间有效 |
捕获外部变量 | 可以捕获外部作用域中的变量(按值或按引用) | 不能直接捕获外部变量,只能通过参数传递 |
调用方式 | 作为函数对象,可直接调用 | 像普通函数一样调用 |
优化 | 可以被编译器自动内联化,但取决于编译器优化策略 | 明确请求编译器尝试内联,但实际内联化也取决于编译器 |
可见性 | 通常只在定义他们的局部作用域内可见 | 可以在定义它的任何作用域内可见 |
使用场景 | 适合于一次性使用的场景,如作为回调、在算法中使用等 | 适合于频繁调用的小型函数 |
虽然 Lambda 函数和内联函数在某些方面有相似之处,如它们都可以被编译器优化以减少调用开销,但它们在设计和用途上有明显的不同。Lambda 函数的核心优势在于它们的匿名性和对外部变量的捕获能力,而内联函数则主要关注于提高小型函数的性能。