【C/C++ 解惑 】C++ 函数对象可以是哪些?

简介: 【C/C++ 解惑 】C++ 函数对象可以是哪些?

C++中的函数对象(也称为函数符或仿函数)是一个定义了operator()的类的对象。函数对象可以像普通函数一样被调用,但它们可以存储状态,这使得它们比普通函数更灵活。

下面是C++中可以是函数对象的一些示例:

1. 类定义了operator()

struct Add {
    int operator()(int a, int b) {
        return a + b;
    }
};
Add add;
int result = add(3, 4);  // 结果是7

2. Lambda表达式

C++11引入了lambda表达式,它们是匿名函数对象。

auto add = [](int a, int b) { return a + b; };
int result = add(3, 4);  // 结果是7

3. 标准库中的函数对象

C++标准库提供了一系列的预定义函数对象,如std::plus, std::minus, std::multiplies, 等等。

#include <functional>
std::plus<int> add;
int result = add(3, 4);  // 结果是7

4. 可调用对象的包装器

std::function是一个通用的可调用对象包装器,它可以存储、复制和调用任何可调用对象,如函数指针、成员函数指针、函数对象和lambda表达式。

#include <functional>
std::function<int(int, int)> add = [](int a, int b) { return a + b; };
int result = add(3, 4);  // 结果是7

5. 绑定表达式

std::bind 返回一个新的函数对象,将原始函数对象的一些参数绑定到特定的值或位置。

#include <functional>
using namespace std::placeholders;
auto add = std::bind(std::plus<int>(), _1, _2);
int result = add(3, 4);  // 结果是7

这些都是C++中函数对象的常见示例。函数对象的使用提供了很大的灵活性,使得你可以在不同的上下文中重用函数逻辑,并且可以存储和传递状态。


std::bindstd::function 是 C++ 标准库中两个不同的部分,它们用于不同的目的,虽然它们都与函数对象和可调用对象有关。

std::bind

std::bind 用于生成一个新的可调用对象,通过绑定一些参数值或占位符到已有的函数、函数对象或其他可调用对象上。std::bind 返回的是一个可调用对象,而不是 std::function 类型。这个返回的可调用对象可以赋值给 std::function,但它自身并不是 std::function 类型。

#include <functional>
auto add = std::bind(std::plus<int>(), std::placeholders::_1, std::placeholders::_2);
// add 的类型是 unspecified, 但不是 std::function

std::function

std::function 是一个类模板,它可以存储、复制和调用任何可调用对象,如函数指针、成员函数指针、函数对象和 lambda 表达式。std::function 的优点是它提供了一个统一的接口来处理所有这些不同类型的可调用对象。

#include <functional>
std::function<int(int, int)> add = std::plus<int>();
// add 是 std::function 类型

区别

  • std::bind 返回一个未指定类型的可调用对象,而 std::function 是一个确定的类模板。
  • std::bind 用于创建新的可调用对象,通过绑定参数;而 std::function 用于存储和调用已有的可调用对象。
  • std::function 可以存储 std::bind 返回的可调用对象,但 std::bind 返回的并不是 std::function 类型。

简单来说,std::bindstd::function 在功能上是互补的,std::bind 用于生成新的可调用对象,而 std::function 用于存储和调用可调用对象。

结语

在我们的编程学习之旅中,理解是我们迈向更高层次的重要一步。然而,掌握新技能、新理念,始终需要时间和坚持。从心理学的角度看,学习往往伴随着不断的试错和调整,这就像是我们的大脑在逐渐优化其解决问题的“算法”。

这就是为什么当我们遇到错误,我们应该将其视为学习和进步的机会,而不仅仅是困扰。通过理解和解决这些问题,我们不仅可以修复当前的代码,更可以提升我们的编程能力,防止在未来的项目中犯相同的错误。

我鼓励大家积极参与进来,不断提升自己的编程技术。无论你是初学者还是有经验的开发者,我希望我的博客能对你的学习之路有所帮助。如果你觉得这篇文章有用,不妨点击收藏,或者留下你的评论分享你的见解和经验,也欢迎你对我博客的内容提出建议和问题。每一次的点赞、评论、分享和关注都是对我的最大支持,也是对我持续分享和创作的动力。

目录
相关文章
|
3月前
|
编译器 C++
C++之类与对象(完结撒花篇)(上)
C++之类与对象(完结撒花篇)(上)
45 0
|
2月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
118 5
|
2月前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
123 4
|
2月前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
161 4
|
3月前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
3月前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
37 4
|
3月前
|
编译器 C语言 C++
【C++打怪之路Lv4】-- 类和对象(中)
【C++打怪之路Lv4】-- 类和对象(中)
36 4
|
3月前
|
存储 前端开发 C++
C++ 多线程之带返回值的线程处理函数
这篇文章介绍了在C++中使用`async`函数、`packaged_task`和`promise`三种方法来创建带返回值的线程处理函数。
110 6
|
3月前
|
C++
C++ 多线程之线程管理函数
这篇文章介绍了C++中多线程编程的几个关键函数,包括获取线程ID的`get_id()`,延时函数`sleep_for()`,线程让步函数`yield()`,以及阻塞线程直到指定时间的`sleep_until()`。
51 0
|
3月前
|
存储 编译器 C++
【C++类和对象(下)】——我与C++的不解之缘(五)
【C++类和对象(下)】——我与C++的不解之缘(五)