Geekban极客班C++STL与泛型编程 第二周

来源:互联网 发布:java 小红本 编辑:程序博客网 时间:2024/05/20 14:17

Set

Set和multiset会根据特定的排序准则,自动将元素排序。
两者不同之处在于multiset允许元素重复,但是set不允许。

Template<class_Kty,class_Pr=less<_Kty>,class_Alloc=allocator<_Kty> >

第一个参数为任意类型T,第二个参数可有可无,定义排序准则,如果没有定义则为less,第三参数定义内存模型,可有可无,默认的内存模型为allocator

两种定义排序准则:
1.以template参数定义std::set<int,std::greater<int>> coll
2.以构造函数参数定义

set的实现不允许通过迭代器改变对象成员!
要改变对象的成员而不是真正的key

std::set<Person,PersonldComparer>::iterator it=ps1.find(Person(L"bill',4));if(it!=ps1.end())   const_cast<Person&>)(*it).SetName(L"BillGates");

一定要cast为对象的引用而不是对象本身

set和multiset的查找操作函数

c.cout(val)返回“元素值为val”的元素个数
c.find(val)返回“元素值为val”的第一个元素,如果找不到就返回end()
c.lower_bound(val)返回val的第一个可安插位置
c.upper_bound(val)返回val的最后一个可安插位置
c.equal_range(val)返回val可被安插的第一个位置和最后一个位置

set和Multiset元素的安插和移除

c.insert(val)安插一个val拷贝,返回元素新位置
c.insert(pos,val)安插一个val拷贝,返回元素新位置
c.inset(beg,end)将[beg,end)内所有元素拷贝安插到c
c.insert(initlist)安插初值列initlist内所有元素的一份拷贝
c.emplace(args…)安插一个以args为初值的元素,并返回新元素的位置
c.emplace_hint(pos,args…)安插一个与args为初值的元素,并返回新元素位置
c.erase(val)移除“与val相等”的所有元素
c.erase(pos)移除iterator位置Pos上的元素
c.erase(beg,end)移除区间[beg,end)内的所有元素
c.clear()移除所有元素,将容器清空

仿函数(Functors)

仿函数又称为函数对象,其作用相当于一个指针。

Algorithm(Iterator first,Iterator last,...,Functor func){   ...   func(...)   ...}

其中仿函数必须是STL内建,或用户自定义

template<typename T>class Functor{   void operator(...){}}

必须重载operator(),以实现函数调用

为什么要用仿函数而不是普通指针作为算法的行为参数?

  1. 普通函数指针不能满足STL的抽象要求
  2. 函数指针无法和STL其他组件交互
  3. 仿函数可作为模板参数用于定义对象的某种默认行为

仿函数适配器

仿函数适配器:将无法匹配的仿函数“套接”成可以匹配的类别

binder1st/binder2nd

这里写图片描述

binder1st/binder2nd的区别
_func操作是作用在左值还是右值

binder1st<_Fn2>bind1st(const _Fn2&_Func,const _Ty&_Left){   typename _Fn2::first_argument_type_Val(_Left);   return (binder1st<_Fn2>(_Func,_Val));}binder2nd<_Fn2>bind2nd(const _Fn2&_Func,const _Ty&_Right){   typename _Fn2::second_argument_type_Val(_Right);   return (binder2nd<_Fn2>(_Func,_Val));

mem_fun和mem_fun_ref

用来适配对象的成员函数。

std::for_each(v.begin(),v.end(),&Person::Print);//编译失败

成员函数不能通过&,取到成员函数的地址

这里写图片描述

非易变算法

是一些列模板函数,在不改变操作对象的前提下对元素进行处理。诸如:查找,子序列搜索,统计,匹配

count/count_if

count(InputIterator beg,InputIterator end,const T& value)count(InputIterator beg,InputIterator end,UnaryPredicate op)
  • 第一形式计算区间[beg,end)中值为value的元素个数
  • 第二形式计算区间[beg,end)中“令unary predicate op(elem)”结果为true”的元素个数
  • 返回类型difference_type,用于表现iterator间距类型
  • 复杂度:线性

最大值最小值

min_element(ForwardIterator beg,ForwardIterator end)min_element(ForwardIterator beg,ForwardIterator end,CompFunc op)max_element(ForwardIterator beg,ForwardIterator end)max_element(ForwardIterator beg,ForwardIterator end,CompFunc op)minmax_element(ForwardIterator beg,ForwardIterator end)minmax_element(ForwardIterator beg,ForwardIterator end,CompFunc op)

查找

find(InputIterator beg,InputIterator end,const T&value)find_if(InputIterator beg,InputIterator end,UnaryPredicate op)fine_if(IuputIterator beg,InputIterator end,UnaryPredicate op)
  • 第二参数返回[beg,end)区间中第一个“造成unary predicate结果为true的元素”:op(elem)
  • 第三参数返回[beg,end)区间中第一个“造成unary predicate结果为flase的元素”:op(elem)
  • 如果是已排序区间,应该使用lower_bound(),upper_bound(),equal_range()或binary_search()算法
  • Associative和unordered容器提供一个等效的成员函数find()

区间的比较

bool equal(InputIterator1 beg,InputIterator1 end,InputIterator2 cmpBeg)bool equal(InputIterator1 beg,InputIterator1 end,InputIterator2 cmpBeg)
  • 第一形式判断[beg,end)区间内的元素是否都和“以cmpBeg开头的区间”内的元素相等
  • 第二形式判断[beg,end)区间内的元素和“以cmpBeg开头的区间”内的对应元素是否都能够造成以下binary predicate产出true: op(elem,cmpElem)
0 0