Lambda表达式:Lambda表达式是一种匿名函数,可以在代码中直接定义和使用。它可以捕获外部变量,并且可以作为函数参数或返回值使用。
std::function:std::function是一个通用的函数封装器,可以存储、复制和调用任何可调用对象,包括函数、函数指针、成员函数指针和Lambda表达式等。
std::bind:std::bind是一个函数适配器,可以将一个可调用对象和一些参数绑定在一起,生成一个新的可调用对象。
std::transform:std::transform是一个函数模板,可以对一个序列中的每个元素应用一个函数,并将结果存储到另一个序列中。
std::accumulate:std::accumulate是一个函数模板,可以对一个序列中的所有元素进行累加或累积操作。
这些特性使得C++11更加适合函数式编程,可以更方便地使用函数式编程的思想和技巧来解决问题。
已在其他篇章中详细描述。
std::function 是一个通用的函数封装器,可以存储、复制和调用任何可调用对象,包括函数、函数指针、成员函数指针和 Lambda 表达式等。下面是 std::function 的使用示例:
#include
#include
int add(int a, int b) {
return a + b;
}
int main() {
std::function<int(int, int)> func = add; // 将函数指针赋值给 std::function 对象
std::cout << func(1, 2) << std::endl; // 输出 3
auto lambda = [](int a, int b) -> int { return a * b; }; // 定义一个 Lambda 表达式
func = lambda; // 将 Lambda 表达式赋值给 std::function 对象
std::cout << func(3, 4) << std::endl; // 输出 12
return 0;
}
在上面的示例中,我们首先定义了一个函数 add
,然后将它的函数指针赋值给了一个 std::function
对象 func
。接着,我们定义了一个 Lambda 表达式 lambda
,并将它赋值给了 func
。最后,我们调用 func
并输出结果。
需要注意的是,std::function
对象的模板参数是函数的签名,即函数的返回值类型和参数类型。在上面的示例中,std::function
表示一个返回值为 int
,有两个 int
类型参数的函数。
std::bind
是一个函数适配器,可以将一个可调用对象和一些参数绑定在一起,生成一个新的可调用对象。下面是 std::bind
的使用示例:
#include
#include
void print(int a, int b, int c) {
std::cout << a << " " << b << " " << c << std::endl;
}
int main() {
auto f1 = std::bind(print, 1, 2, 3); // 绑定函数和参数
f1(); // 输出 1 2 3
auto f2 = std::bind(print, std::placeholders::_1, std::placeholders::_2, 4); // 绑定函数和部分参数
f2(5, 6); // 输出 5 6 4
auto f3 = std::bind(print, std::placeholders::_2, std::placeholders::_1, std::placeholders::_3); // 绑定函数和参数,但是交换了参数的顺序
f3(7, 8, 9); // 输出 8 7 9
return 0;
}
在上面的示例中,我们首先定义了一个函数 print
,它接受三个 int
类型的参数,并将它们输出到标准输出流中。接着,我们使用 std::bind
函数将 print
函数和一些参数绑定在一起,生成了三个新的可调用对象 f1
、f2
和 f3
。其中,f1
绑定了 print
函数和三个参数,f2
绑定了 print
函数和两个参数,其中第三个参数使用了占位符 std::placeholders::_1
和 std::placeholders::_2
,表示在调用 f2
时需要传入两个 int
类型的参数,而第三个参数已经被绑定为 4
。f3
绑定了 print
函数和三个参数,但是交换了第一个和第二个参数的顺序。
最后,我们调用了这三个可调用对象,并输出了它们的结果。需要注意的是,std::bind
函数返回的是一个可调用对象,需要使用函数调用运算符 ()
来调用它。
std::transform
是一个函数模板,可以对一个序列中的每个元素应用一个函数,并将结果存储到另一个序列中。下面是 std::transform
的使用示例:
#include
#include
#include
int square(int x) {
return x * x;
}
int main() {
std::vector<int> v1 = {1, 2, 3, 4, 5};
std::vector<int> v2(v1.size());
std::transform(v1.begin(), v1.end(), v2.begin(), square); // 对 v1 中的每个元素应用 square 函数,并将结果存储到 v2 中
for (auto x : v2) {
std::cout << x << " ";
}
std::cout << std::endl; // 输出 1 4 9 16 25
return 0;
}
在上面的示例中,我们首先定义了一个函数 square
,它接受一个 int
类型的参数,并返回它的平方。接着,我们定义了一个 std::vector
对象 v1
,并初始化它的元素为 {1, 2, 3, 4, 5}
。然后,我们定义了另一个 std::vector
对象 v2
,并使用 std::transform
函数对 v1
中的每个元素应用 square
函数,并将结果存储到 v2
中。最后,我们遍历 v2
中的元素,并输出它们的值。
需要注意的是,std::transform
函数的前两个参数是输入序列的起始和终止迭代器,第三个参数是输出序列的起始迭代器,第四个参数是一个可调用对象,用于对输入序列中的每个元素进行操作。在上面的示例中,我们使用了函数指针 square
作为可调用对象。
std::accumulate
是一个函数模板,可以对一个序列中的所有元素进行累加或累积操作。下面是 std::accumulate
的使用示例:
#include
#include
#include
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
int sum = std::accumulate(v.begin(), v.end(), 0); // 对 v 中的所有元素进行累加操作,初始值为 0
std::cout << sum << std::endl; // 输出 15
return 0;
}
在上面的示例中,我们定义了一个 std::vector
对象 v
,并初始化它的元素为 {1, 2, 3, 4, 5}
。然后,我们使用 std::accumulate
函数对 v
中的所有元素进行累加操作,并将结果存储到变量 sum
中。最后,我们输出 sum
的值。
需要注意的是,std::accumulate
函数的前两个参数是输入序列的起始和终止迭代器,第三个参数是累加的初始值。在上面的示例中,我们将初始值设为 0
,表示从 0
开始累加。如果输入序列中的元素类型不是整数类型,需要提供一个自定义的累加函数作为第四个参数。