C++

C++ 知识量:19 - 82 - 316

10.2 定制操作><

向算法传递函数- 10.2.1 -

在C++泛型算法中,可以使用函数指针、函数对象或者Lambda函数向算法传递函数。这些函数将在算法执行时被调用,以实现自定义的操作。

以下是一些向C++泛型算法传递函数的示例:

1. 使用函数指针

#include <iostream>  
#include <algorithm>  
#include <vector>  
  
// 定义一个函数,用于向泛型算法传递函数  
int add(int a, int b) {  
    return a + b;  
}  
  
int main() {  
    std::vector<int> v = {1, 2, 3, 4, 5};  
    std::sort(v.begin(), v.end(), add);  // 使用函数指针作为比较函数  
  
    for (auto i : v) {  
        std::cout << i << " ";  
    }  
    std::cout << std::endl;  
  
    return 0;  
}

2. 使用函数对象

#include <iostream>  
#include <algorithm>  
#include <vector>  
#include <functional>  
  
// 定义一个函数对象,用于向泛型算法传递函数  
struct Add {  
    int operator()(int a, int b) const {  
        return a + b;  
    }  
};  
  
int main() {  
    std::vector<int> v = {1, 2, 3, 4, 5};  
    std::sort(v.begin(), v.end(), Add());  // 使用函数对象作为比较函数  
  
    for (auto i : v) {  
        std::cout << i << " ";  
    }  
    std::cout << std::endl;  
  
    return 0;  
}

3. 使用Lambda函数

#include <iostream>  
#include <algorithm>  
#include <vector>  
  
int main() {  
    std::vector<int> v = {1, 2, 3, 4, 5};  
    std::sort(v.begin(), v.end(), [](int a, int b) { return a + b; });  // 使用Lambda函数作为比较函数  
  
    for (auto i : v) {  
        std::cout << i << " ";  
    }  
    std::cout << std::endl;  
  
    return 0;  
}

lambda表达式- 10.2.2 -

C++的lambda表达式是一种匿名函数,可以方便地定义并使用简洁的函数。

下面是一个简单的lambda表达式的示例:

auto add = [](int a, int b) { return a + b; };  
int result = add(1, 2);  // result的值为3

在这个例子中,[](int a, int b) { return a + b; }是一个lambda表达式,它接受两个整数参数并返回它们的和。通过将这个表达式赋值给变量add,创建了一个可以像普通函数一样调用的函数对象。

lambda表达式的语法如下:

[capture list] (parameter list) { body }

其中,capture list用于指定捕获的变量或表达式,parameter list指定参数的类型和名称,body是函数体。如果不需要捕获任何变量,则可以省略capture list。如果函数体只有一条语句,则可以省略大括号。

lambda表达式的捕获机制与普通函数类似,可以使用值捕获或引用捕获。值捕获将变量复制到lambda表达式中,而引用捕获将变量的引用传递给lambda表达式。如果需要在lambda表达式中修改捕获的变量,则应该使用引用捕获。

下面是一个使用引用捕获的示例:

int x = 10;  
auto add = [&x](int a, int b) { return x + a + b; };  
x = 20;  
int result = add(1, 2);  // result的值为23

在这个例子中,使用&x将变量x的引用传递给lambda表达式。在lambda表达式中,可以修改捕获的变量并影响外部变量的值。

lambda捕获和返回- 10.2.3 -

在C++泛型算法中,lambda表达式可以捕获外部变量,并可以在函数体内使用这些变量。此外,lambda表达式还可以返回值。

以下是一个使用lambda表达式捕获外部变量并返回值的示例:

#include <iostream>  
#include <vector>  
#include <algorithm>  
  
int main() {  
    std::vector<int> v = {1, 2, 3, 4, 5};  
    int x = 0;  
  
    std::for_each(v.begin(), v.end(), [&](int i) {  
        x += i;  
    });  
  
    std::cout << "Sum: " << x << std::endl;  // 输出 Sum: 15  
  
    return 0;  
}

在上面的例子中,使用了std::for_each算法,并传递了一个lambda表达式作为操作函数。lambda表达式捕获了外部变量x,并在函数体内对x进行累加。最后,x的值被输出到控制台。

如果需要在lambda表达式中返回一个值,可以使用return语句。例如:

#include <iostream>  
#include <vector>  
#include <algorithm>  
  
int main() {  
    std::vector<int> v = {1, 2, 3, 4, 5};  
    int sum = 0;  
  
    std::for_each(v.begin(), v.end(), [&](int i) {  
        return sum += i;  // 返回 sum 的值,并累加到外部变量 sum 中  
    });  
  
    std::cout << "Sum: " << sum << std::endl;  // 输出 Sum: 15  
  
    return 0;  
}

在上面的例子中,lambda表达式返回了sum的值,并将其累加到外部变量sum中。最后,sum的值被输出到控制台。

参数绑定- 10.2.4 -

在C++中,可以使用std::bind函数来绑定函数的参数。std::bind函数可以将一个函数的部分参数绑定为特定的值,生成一个新的可调用对象(callable),该对象可以被当作其他函数的参数使用。

以下是一个使用std::bind绑定函数参数的示例:

#include <iostream>  
#include <functional>  
  
void print_sum(int a, int b) {  
    std::cout << a + b << std::endl;  
}  
  
int main() {  
    int x = 10;  
    auto bound_print_sum = std::bind(print_sum, std::placeholders::_1, x);  // 将 x 绑定为 print_sum 的第二个参数  
    bound_print_sum(20);  // 输出 30  
    x = 5;  
    bound_print_sum(30);  // 输出 40  
    return 0;  
}

在上面的示例中,首先定义了一个名为print_sum的函数,该函数接受两个整数参数并输出它们的和。然后,使用std::bind将print_sum函数的第二个参数x绑定为特定的值。这里使用了std::placeholders::_1占位符来表示第一个未绑定的参数。生成的可调用对象bound_print_sum可以被当作其他函数的参数使用。在示例中,分别将20和30作为参数调用bound_print_sum,并输出结果。由于x的值在绑定时被确定,因此无论何时调用bound_print_sum,它都将使用相同的x值。