目录
内联函数
其定义直接在每个调用点展开。这意味着编译器 会尝试将函数调用替换为函数本身的代码,这样可以减少函数调用的开销,尤其是在小型函数中
特点
- .减少函数调用开销:内联函数通常用于优化小型、频繁调用的函数,因为它避免了函数调用的常规 开销(如参数传递、栈操作等)。
- 编译器决策:即使函数被声明为内联,编译器也可能决定不进行内联,特别是对于复杂或递归函 数。
- 适用于小型函数:通常只有简单的、执行时间短的函数适合做内联。
- 定义在每个使用点:内联函数的定义(而非仅仅是声明)必须对每个使用它的文件都可见,通常意 味着将内联函数定义在头文件中。
使用方法
inline int add(int a, int b) {
return a + b;
}
int result = add(5, 3); // 编译器可能会将此替换为:int result = 5 + 3;
std::cout << "Result: " << result << std::endl;
注意
- 过度使用的风险:不应滥用内联函数,因为这可能会增加最终程序的大小(代码膨胀)。对于大型 函数或递归函数,内联可能导致性能下降。
- 编译器的决定:最终是否将函数内联是由编译器决定的,即使函数被标记为 inline 。
- 适用场景:最适合内联的是小型函数和在性能要求高的代码中频繁调用的函数。
Lambda 表达式
Lambda 表达式是 C++11 引入的一种匿名函数的方式,它允许你在需要函数的地方内联地定义函数,而 无需单独命名函数
基本语法
[capture clause](parameters) -> return_type {
// 函数体
// 可以使用捕获列表中的变量
return expression; // 可选的返回语句
}
- 捕获列表(Capture clause):用于捕获外部变量,在 Lambda 表达式中可以访问这些变量。捕 获列表可以为空,也可以包含变量列表 [var1, var2, ...] 。
- 参数列表(Parameters):与普通函数的参数列表类似,可以为空或包含参数列表 (param1, param2, ...) 。
- 返回类型(Return type):Lambda 表达式可以自动推断返回类型auto,也可以显式指定返回类 型 -> return_type 。如果函数体只有一条返回语句,可以省略返回类型。
- 函数体(Body):Lambda 表达式的函数体,包含需要执行的代码。
示例1:使用 Lambda 表达式进行加法
// 定义一个简单的 Lambda 表达式进行加法
auto add = [](int a, int b) {
return a + b;
};
// 使用 Lambda 表达式计算两个数的和
int sum = add(10, 20);
std::cout << "Sum is: " << sum << std::endl;
示例2:在函数调用中使用匿名 lambda 函数
使用一个函数来找出两个数中的较大数,这个函数将接受一个 lambda 函数 作为回调来比较这两个数。Lambda 函数将直接在函数调用时定义,完全是匿名的
// 函数,接受两个整数和一个比较的 lambda 函数
bool myCompare(int a, int b){
return a > b;
}
int getMax(int a, int b, bool(*compare)(int, int)) {
if (compare(a, b)) {
return a;
} else {
return b;
}
}
int x = 10;
int y = 20;
// 回调函数
int max = getMax(x, y, myCompare);
std::cout << "The larger number is: " << max << std::endl;
或者可以写成
// 函数,接受两个整数和一个比较的 lambda 函数
int getMax(int a, int b, bool(*compare)(int, int)) {
if (compare(a, b)) {
return a;
} else {
return b;
}
}
int x = 10;
int y = 20;
// 直接在函数调用中定义匿名 lambda 函数
int max = getMax(x, y, [](int a, int b) -> bool {
return a > b;
});
std::cout << "The larger number is: " << max << std::endl;
- getMax 函数接受两个整数 a 和 b ,以及一个比较函数 compare 。这个比较函数是一个指向函数 的指针,它接受两个整数并返回一个布尔值。
- 在 main 函数中,我们调用 getMax ,并直接在调用点定义了一个匿名的 lambda 函数。这个 lambda 函数接受两个整数并返回一个表示第一个整数是否大于第二个整数的布尔值
- 这个 lambda 函数在 getMax 中被用作比较两个数的逻辑。根据 lambda 函数的返回值, getMax 返回较大的数
示例3:带参数捕获的 Lambda 表达式
int x = 10;
int y = 20;
// 捕获 x 和 y 以便在 Lambda 内部使用
// 这里的捕获列表 [x, y] 表示 x 和 y 被按值捕获
auto sum = [x, y]() {
// x++;
// y++; 按值捕获,关注的是值本身,无法修改
return x + y;
};
std::cout << "Sum is: " << sum() << std::endl;
std::cout << "x is now: " << x << ", y is now: " << y << std::endl;
// 捕获所有外部变量按值捕获(拷贝)
int z = 30;
auto multiply = [=]() {
// x++;
// y++; 按值捕获,关注的是值本身,无法修改
return x * y * z;
};
count << x << "," << y << endl;
std::cout << "Product is: " << multiply() << std::endl;
std::cout << "x is now: " << x << ", y is now: " << y << std::endl;
// 捕获所有外部变量按引用捕获
auto modifyAndSum = [&]() {
x = 15; // 修改 x 的实际值
y = 25; // 修改 y 的实际值, 引用捕获可以修改
return x + y;
};
std::cout << "Modified Sum is: " << modifyAndSum() << std::endl;
std::cout << "x is now: " << x << ", y is now: " << y << std::endl;
- 第一个 Lambda 表达式 sum 按值捕获了 x 和 y (即它们的副本)。这意味着 sum 内的 x 和 y 是在 Lambda 定义时的值的拷贝。
- 第二个 Lambda 表达式 multiply 使用 [=] 捕获列表,这表示它按值捕获所有外部变量。
- 第三个 Lambda 表达式 modifyAndSum 使用 [&] 捕获列表,这表示它按引用捕获所有外部变量。 因此,它可以修改 x 和 y 的原始值。