C++模板与STL【函数对象】

简介: C++模板与STL【函数对象】



1 STL- 函数对象

🏆1.1 函数对象

🍉1.1.1 函数对象概念

概念:

  • 重载函数调用操作符的类,其对象常称为函数对象
  • 函数对象使用重载的()时,行为类似函数调用,也叫仿函数

本质:

函数对象(仿函数)是一个,不是一个函数

🍉1.1.2 函数对象使用

特点:

  • 函数对象在使用时,可以像普通函数那样调用, 可以有参数,可以有返回值
  • 函数对象超出普通函数的概念,函数对象可以有自己的状态
  • 函数对象可以作为参数传递

示例:

#include <string>
//1、函数对象在使用时,可以像普通函数那样调用, 可以有参数,可以有返回值
class MyAdd
{
public :
  int operator()(int v1,int v2)
  {
    return v1 + v2;
  }
};
void test01()
{
  MyAdd myAdd;
  cout << myAdd(10, 10) << endl;
}
//2、函数对象可以有自己的状态
class MyPrint
{
public:
  MyPrint()
  {
    count = 0;
  }
  void operator()(string test)
  {
    cout << test << endl;
    count++; //统计使用次数
  }
  int count; //内部自己的状态
};
void test02()
{
  MyPrint myPrint;
  myPrint("hello world");
  myPrint("hello world");
  myPrint("hello world");
  cout << "myPrint调用次数为: " << myPrint.count << endl;
}
//3、函数对象可以作为参数传递
void doPrint(MyPrint &mp , string test)
{
  mp(test);
}
void test03()
{
  MyPrint myPrint;
  doPrint(myPrint, "Hello C++");
}
int main() {
  //test01();
  //test02();
  test03();
  system("pause");
  return 0;
}

总结:

  • 仿函数写法非常灵活,可以作为参数进行传递。

🏆1.2 谓词

🥭1.2.1 谓词概念

概念:

  • 返回bool类型的仿函数称为谓词
  • 如果operator()接受一个参数,那么叫做一元谓词
  • 如果operator()接受两个参数,那么叫做二元谓词
🥭1.2.2 一元谓词

示例:

#include <vector>
#include <algorithm>
//1.一元谓词
struct GreaterFive{
  bool operator()(int val) {
    return val > 5;
  }
};
void test01() {
  vector<int> v;
  for (int i = 0; i < 10; i++)
  {
    v.push_back(i);
  }
  vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFive());
  if (it == v.end()) {
    cout << "没找到!" << endl;
  }
  else {
    cout << "找到:" << *it << endl;
  }
}
int main() {
  test01();
  system("pause");
  return 0;
}

总结:参数只有一个的谓词,称为一元谓词

🥭1.2.3 二元谓词

示例:

#include <vector>
#include <algorithm>
//二元谓词
class MyCompare
{
public:
  bool operator()(int num1, int num2)
  {
    return num1 > num2;
  }
};
void test01()
{
  vector<int> v;
  v.push_back(10);
  v.push_back(40);
  v.push_back(20);
  v.push_back(30);
  v.push_back(50);
  //默认从小到大
  sort(v.begin(), v.end());
  for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
  {
    cout << *it << " ";
  }
  cout << endl;
  cout << "----------------------------" << endl;
  //使用函数对象改变算法策略,排序从大到小
  sort(v.begin(), v.end(), MyCompare());
  for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
  {
    cout << *it << " ";
  }
  cout << endl;
}
int main() {
  test01();
  system("pause");
  return 0;
}

总结:参数只有两个的谓词,称为二元谓词

🏆1.3 内建函数对象

🍍1.3.1 内建函数对象意义

概念:

  • STL内建了一些函数对象

分类:

  • 算术仿函数
  • 关系仿函数
  • 逻辑仿函数

用法:

  • 这些仿函数所产生的对象,用法和一般函数完全相同
  • 使用内建函数对象,需要引入头文件 #include<functional>
🍍1.3.2 算术仿函数

功能描述:

  • 实现四则运算
  • 其中negate是一元运算,其他都是二元运算

仿函数原型:

  • template<class T> T plus<T> //加法仿函数
  • template<class T> T minus<T> //减法仿函数
  • template<class T> T multiplies<T> //乘法仿函数
  • template<class T> T divides<T> //除法仿函数
  • template<class T> T modulus<T> //取模仿函数
  • template<class T> T negate<T> //取反仿函数

示例:

#include <functional>
//negate
void test01()
{
  negate<int> n;
  cout << n(50) << endl;
}
//plus
void test02()
{
  plus<int> p;
  cout << p(10, 20) << endl;
}
int main() {
  test01();
  test02();
  system("pause");
  return 0;
}

总结:使用内建函数对象时,需要引入头文件 #include <functional>

🍍1.3.3 关系仿函数

功能描述:

  • 实现关系对比

仿函数原型:

  • template<class T> bool equal_to<T> //等于
  • template<class T> bool not_equal_to<T> //不等于
  • template<class T> bool greater<T> //大于
  • template<class T> bool greater_equal<T> //大于等于
  • template<class T> bool less<T> //小于
  • template<class T> bool less_equal<T> //小于等于

示例:

#include <functional>
#include <vector>
#include <algorithm>
class MyCompare
{
public:
  bool operator()(int v1,int v2)
  {
    return v1 > v2;
  }
};
void test01()
{
  vector<int> v;
  v.push_back(10);
  v.push_back(30);
  v.push_back(50);
  v.push_back(40);
  v.push_back(20);
  for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
    cout << *it << " ";
  }
  cout << endl;
  //自己实现仿函数
  //sort(v.begin(), v.end(), MyCompare());
  //STL内建仿函数  大于仿函数
  sort(v.begin(), v.end(), greater<int>());
  for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
    cout << *it << " ";
  }
  cout << endl;
}
int main() {
  test01();
  system("pause");
  return 0;
}

总结:关系仿函数中最常用的就是greater<>大于

🍍1.3.4 逻辑仿函数

功能描述:

  • 实现逻辑运算

函数原型:

  • template<class T> bool logical_and<T> //逻辑与
  • template<class T> bool logical_or<T> //逻辑或
  • template<class T> bool logical_not<T> //逻辑非

示例:

#include <vector>
#include <functional>
#include <algorithm>
void test01()
{
  vector<bool> v;
  v.push_back(true);
  v.push_back(false);
  v.push_back(true);
  v.push_back(false);
  for (vector<bool>::iterator it = v.begin();it!= v.end();it++)
  {
    cout << *it << " ";
  }
  cout << endl;
  //逻辑非  将v容器搬运到v2中,并执行逻辑非运算
  vector<bool> v2;
  v2.resize(v.size());
  transform(v.begin(), v.end(),  v2.begin(), logical_not<bool>());
  for (vector<bool>::iterator it = v2.begin(); it != v2.end(); it++)
  {
    cout << *it << " ";
  }
  cout << endl;
}
int main() {
  test01();
  system("pause");
  return 0;
}

总结:逻辑仿函数实际应用较少,了解即可

🕮 2 总结

在代码的舞台上,C++翩翩起舞。

纵观代码的山川大地,无边的可能在眼前延展, C++,是智慧的风,吹动着科技的帆船。

用韵律的二进制,谱写着自由的交响曲, C++,是数字艺术的荣光,闪烁在信息的星空。

愿C++永远如诗,激励创造者的灵感。

渴望挑战C++的学习路径和掌握进阶技术?不妨点击下方链接,一同探讨更多C++的奇迹吧。我们推出了引领趋势的💻C++专栏:《C++从基础到进阶》 ,旨在深度探索C++的实际应用和创新。🌐🔍

目录
打赏
0
0
0
0
14
分享
相关文章
㉿㉿㉿c++模板的初阶(通俗易懂简化版)㉿㉿㉿
㉿㉿㉿c++模板的初阶(通俗易懂简化版)㉿㉿㉿
|
25天前
|
【c++丨STL】stack和queue的使用及模拟实现
本文介绍了STL中的两个重要容器适配器:栈(stack)和队列(queue)。容器适配器是在已有容器基础上添加新特性或功能的结构,如栈基于顺序表或链表限制操作实现。文章详细讲解了stack和queue的主要成员函数(empty、size、top/front/back、push/pop、swap),并提供了使用示例和模拟实现代码。通过这些内容,读者可以更好地理解这两种数据结构的工作原理及其实现方法。最后,作者鼓励读者点赞支持。 总结:本文深入浅出地讲解了STL中stack和queue的使用方法及其模拟实现,帮助读者掌握这两种容器适配器的特性和应用场景。
55 21
|
1月前
|
【C++面向对象——类与对象】Computer类(头歌实践教学平台习题)【合集】
声明一个简单的Computer类,含有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等等,以及两个公有成员函数run、stop。只能在类的内部访问。这是一种数据隐藏的机制,用于保护类的数据不被外部随意修改。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。成员可以在派生类(继承该类的子类)中访问。成员,在类的外部不能直接访问。可以在类的外部直接访问。为了完成本关任务,你需要掌握。
68 19
【C++面向对象——类与对象】CPU类(头歌实践教学平台习题)【合集】
声明一个CPU类,包含等级(rank)、频率(frequency)、电压(voltage)等属性,以及两个公有成员函数run、stop。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。​ 相关知识 类的声明和使用。 类的声明和对象的声明。 构造函数和析构函数的执行。 一、类的声明和使用 1.类的声明基础 在C++中,类是创建对象的蓝图。类的声明定义了类的成员,包括数据成员(变量)和成员函数(方法)。一个简单的类声明示例如下: classMyClass{ public: int
51 13
【c++丨STL】list模拟实现(附源码)
本文介绍了如何模拟实现C++中的`list`容器。`list`底层采用双向带头循环链表结构,相较于`vector`和`string`更为复杂。文章首先回顾了`list`的基本结构和常用接口,然后详细讲解了节点、迭代器及容器的实现过程。 最终,通过这些步骤,我们成功模拟实现了`list`容器的功能。文章最后提供了完整的代码实现,并简要总结了实现过程中的关键点。 如果你对双向链表或`list`的底层实现感兴趣,建议先掌握相关基础知识后再阅读本文,以便更好地理解内容。
45 1
【c++丨STL】list的使用
本文介绍了STL容器`list`的使用方法及其主要功能。`list`是一种双向链表结构,适用于频繁的插入和删除操作。文章详细讲解了`list`的构造函数、析构函数、赋值重载、迭代器、容量接口、元素访问接口、增删查改操作以及一些特有的操作接口如`splice`、`remove_if`、`unique`、`merge`、`sort`和`reverse`。通过示例代码,读者可以更好地理解如何使用这些接口。最后,作者总结了`list`的特点和适用场景,并预告了后续关于`list`模拟实现的文章。
69 7
【c++丨STL】vector的使用
本文介绍了C++ STL中的`vector`容器,包括其基本概念、主要接口及其使用方法。`vector`是一种动态数组,能够根据需要自动调整大小,提供了丰富的操作接口,如增删查改等。文章详细解释了`vector`的构造函数、赋值运算符、容量接口、迭代器接口、元素访问接口以及一些常用的增删操作函数。最后,还展示了如何使用`vector`创建字符串数组,体现了`vector`在实际编程中的灵活性和实用性。
136 4
【c++丨STL】string模拟实现(附源码)
本文详细介绍了如何模拟实现C++ STL中的`string`类,包括其构造函数、拷贝构造、赋值重载、析构函数等基本功能,以及字符串的插入、删除、查找、比较等操作。文章还展示了如何实现输入输出流操作符,使自定义的`string`类能够方便地与`cin`和`cout`配合使用。通过这些实现,读者不仅能加深对`string`类的理解,还能提升对C++编程技巧的掌握。
141 5
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
90 2
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等