函数是一组一起执行一个任务的语句。每个 C++ 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数。
您可以把代码划分到不同的函数中。如何划分代码到不同的函数中是由您来决定的,但在逻辑上,划分通常是根据每个函数执行一个特定的任务来进行的。
函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体。
C++ 标准库提供了大量的程序可以调用的内置函数。例如,函数 strcat() 用来连接两个字符串,函数 memcpy() 用来复制内存到另一个位置。
函数还有很多叫法,比如方法、子例程或程序,等等。
Lambda 函数与表达式
Lambda函数的语法定义如下:
[capture](parameters) mutable ->return-type{statement}
其中:
[capture]:捕捉列表。捕捉列表总是出现在 lambda 表达式的开始处。事实上,[] 是 lambda 引出符。编译器根据该引出符判断接下来的代码是否是 lambda 函数。捕捉列表能够捕捉上下文中的变量供 lambda 函数使用。
(parameters):参数列表。与普通函数的参数列表一致。如果不需要参数传递,则可以连同括号 () 一起省略。
mutable:mutable 修饰符。默认情况下,lambda 函数总是一个 const 函数,mutable 可以取消其常量性。在使用该修饰符时,参数列表不可省略(即使参数为空)。
->return_type:返回类型。用追踪返回类型形式声明函数的返回类型。出于方便,不需要返回值的时候也可以连同符号 -> 一起省略。此外,在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行推导。
{statement}:函数体。内容与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。
在 lambda 函数的定义式中,参数列表和返回类型都是可选部分,而捕捉列表和函数体都可能为空,C++ 中最简单的 lambda 函数只需要声明为:
[]{};
两个实际应用到lambda表达式的代码。
std::vector<int> v = { 1, 2, 3, 4, 5, 6 };
int even_count = 0;
for_each(v.begin(), v.end(), [&even_count](int val){
if(!(val & 1)){
++ even_count;
}
});
std::cout << "The number of even is " << even_count << std::endl;
int count = std::count_if( coll.begin(), coll.end(), [](int x){ return x > 10; });
int count = std::count_if( coll.begin(), coll.end(), [](int x){ return x < 10; });
int count = std::count_if( coll.begin(), coll.end(), [](int x){ return x > 5 && x<10; });
[]:默认不捕获任何变量;
[=]:默认以值捕获所有变量;
[&]:默认以引用捕获所有变量;
[x]:仅以值捕获x,其它变量不捕获;
[&x]:仅以引用捕获x,其它变量不捕获;
[=, &x]:默认以值捕获所有变量,但是x是例外,通过引用捕获;
[&, x]:默认以引用捕获所有变量,但是x是例外,通过值捕获;
[this]:通过引用捕获当前对象(其实是复制指针);
[*this]:通过传值方式捕获当前对象;
特殊说明
[this]: 通过引用捕获当前对象(对象本身)
[*this]: 通过传值捕获当前对象(对象拷贝,且只是一个地址值,可以说没有意义)
举例说明:
#include <iostream>
using namepsace std;
//定义一个类
class MM
{
public:
void print() {}
};
int main()
{
MM mm;
//打印对象地址作对比
cout << "对象本身地址:" << &mm << endl;
[&mm](){cout << "[&mm]: " << &mm << endl;}(); //相当于[this]
[mm](){cout << "[mm]: " << &mm << endl;}(); //相当于[*this]
[mm](){cout << "[mm]: " << &mm << endl;}(); //相当于[*this]
return 0;
}
结果:
对象本身地址:012FF984
[&mm]: 012FF984
[mm]: 012FF878
[mm]: 012FF850
尝试将捕获的指针调用成员函数:
[&mm](){cout << this->print();}(); //相当于[this]
//[mm](){cout << this->print();}(); //相当于[*this],无法调用,因为传入的只是一个值
一个新手可能会犯的错误
由于在实际写代码过程中,可能会与到函数的定义和声明不在同一文件,声明出现在头文件中的情况
这时,对带默认值的函数在声明和定义时,需要注意,默认值出现在声明的代码中,定义中不能再对参数赋与默认值,否则会报错。
<Plus.h> //声明在头文件中
int Plus(int a, int b = 10)
<Plus.cpp>//定义在cpp文件中
int Plus(int a, int b)//不能再对b赋值了
{
return a + b;
}