ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

标准模板库、容器类、迭代器、函数对象

2022-05-28 23:34:52  阅读:148  来源: 互联网

标签:容器 begin 函数 迭代 vector books 模板


标准模板库

  1. 迭代器

  • 迭代器能够用来遍历容器的对象;函数对象是类似于函数的对象,可以是类对象或函数指针(包括函数名因为函数名被用作指针);STL 不是面向对象的编程,而是泛型编程;

  1. 模板类 vector p546

  • STL 在头文件 vector 中定义了一个 vector 模板;vector 模板使用动态内存分配,因此可以用初始化参数来指出需要多少矢量:

#include <vector>
using namespace std;
vector<int> ratings(5); // a vector of 5 ints
int n;
cin >> n;
vector<double> scores(n); // a vector of n doubles

与 string 类相似,各种 STL 容器模板都接受一个可选的模板参数,该参数指定使用哪个分配器对象来管理内存。如,vector 模板的开头与下面类似:

template <class T, class Allocator = allocator<T>>
   class vector{...}

如果该模板省略参数的值,则容器模板将默认使用 allocator<T> 类。这个类使用 new 和 delete。

  • 对矢量可执行的操作 p547

size() :返回容器中元素数目 swap():交换两个容器的内容 begin():返回一个指向容器中第一个元素的迭代器 end():返回一个表示超过容器尾的迭代器,即 end() 成员函数标识超过结尾的位置 push_back():将元素添加到矢量末尾 erase():删除矢量中给定区间的元素;它接受两个迭代器参数,第一个迭代器指向区间的起始处,第二个迭代器指向区间终止处的后一个位置 insert():接受 3 个迭代器参数,第一个参数指定新元素插入的位置,第二个和第三个爹嗲气参数定义了被插入区间

每个容器类都定义了一个合适的迭代器;要为 vector 的 double 类型规范声明一个迭代器,可以:

vector<double>::iterator pd; // pd an iterator
vector<double> scores;
pd = scores.begin(); // have pd point to the first element
*pd = 22.3;
++pd;

此外,在初始化迭代器时,也可以使用 auto

auto pd = scores.begin(); // C++11 automatic type deduction
  1. STL 从更广泛的角度定义了非成员(non-member)函数来执行这些操作,即不是为每个容器类定义 find() 函数,而是定义了一个适用于所有容器类的非成员函数 find()。另一方面,即使有执行相同任务的非成员函数,STL 有时也会定义一个成员函数,这是因为对有些操作来说,类特定算法比通用算法高,例如,vector 的成员函数 swap() 的效率比非成员函数 swap() 高。 p550

3 个具有代表性的 STL 函数:for_each()、random_shuffle() 和 sort():

  • for_each()

for_each() 接受 3 个参数,前两个是定义容器中区间的迭代器,最后一个是一个函数对象;for_each() 函数将被指向的函数应用于容器区间中的各个元素;被指向的元素不能修改容器元素的值。可以用 for_each() 函数来代替 for 循环,如:

struct Review{
   std::string title;
   int rating;
};
...
vector<Review> books;
...
vector<Review>::iterator pr;
for (pr = books.begin(); pr != books.end(); pr++)
   ShowReview(*pr);

替换为:

for_each(books.begin(), books.end(), ShowReview);

这样可以避免显式地使用迭代器变量。

  • random_shuffer()

Random_shuffer() 函数接受两个指定区间地迭代器参数,并随机排列该区间中的元素。例如,下面的语句随机排列 books 矢量中的所有元素:

random_shuffle(books.begin(), books.end())

与可用于任何容器类的 for_each() 不同,该函数要求容器类允许随机访问,vector 类可以做到这一点。

  • sort()

sort() 函数也要求容器支持随机访问。该函数有两个版本,第一个版本接受两个定义区间的迭代器参数,并使用为存储在容器中的 < 运算符,对区间中的元素进行操作。例如,下面的语句按升序对 coolstuff 的内容进行排序,排序时使用内置的 < 运算符对值进行比较:

vector<int> coolstuff;
...
sort(coolsutff.begin(), coolstuff.end());

如果容器元素是用户自定义的对象,则要使用 sort(),必须定义能够处理该类型对象的 operator<() 函数(即重载 < 运算符);即,如果为 Review 提供了成员或非成员函数 operator<(),则可以对包含 Review 对象的矢量进行排序。

由于

Review 是一个结构,其成员是公有的,因此可以定义这样的非成员函数(不需是友元)

book operator<(const Review & r1, const Review & r2)
{
   if (r1.title < r2.title)
       return true;
   else if (r1.title == r2.title && r1.rating < r2.rating)
       return true;
   else
       return false;
}

有了上述函数后,可以对包含 Review 对象(如 books)的矢量进行排序:

sort(books.begin(), books.end());

如果按照降序排序,可以使用第二个版本的 sort(),它接受 3 个参数,前两个参数是指定区间的迭代器,最后一个参数是函数对象。

book WorseThan(const Review & r1, const Review & r2)
{
   if (r1.rating < r2.rating)
       return true;
   else
       return false;
}
...
sort(books.begin(), books.end(), WorseThan);
  1. 基于范围的 for 循环(C++11)

基于范围的 for 循环是为用于 STL 而设计的,以下是一个示例

double prices[5] = {4.99, 10.99, 6.87, 7.99, 8.49};
for (double x : prices)
   cout << x << std::endl;

在这种 for 循环中,括号内的代码声明一个类型与容器存储的内容相同的变量,然后指出了容器的名称;接下来,循环体使用指定的变量一次访问容器的每个元素。例如,对于:

for_each(books.begin(), books.end(), ShowReview);

可以更改为:

for (auto x : books) ShowReview(x);

不同于 for_each(),基于范围的 for 循环可以修改容器的内容(利用将参数设置为引用的方法):

void InflateReview(Review &r){r.rating++;}

可使用如下循环对 books 的每个元素执行该函数:

for (auto & x : books) InflateReview(x);

 

 

 

 

 

 

 

 

 

 



标签:容器,begin,函数,迭代,vector,books,模板
来源: https://www.cnblogs.com/San-Francisco/p/16322516.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有