forward_list迭代器不支持递减运算符(–)
构成迭代器范围的迭代器有什么限制:
两个迭代器begin和end必须指向同一个容器中的元素,或者是容器最后一个元素之后的位置;而且,对begin反复进行递增操作,可保证达到end,即end不在begin之前。
练习9.4
#include <iostream>
#include <vector>
using namespace std;
bool search_vec(vector<int>::iterator beg,
vector<int>::iterator end, int val)
{
for (; beg != end;beg++)
{
if (*beg==val)
{
return true;
}
return false;
}
}
int main()
{
vector<int> iList = { 1, 2, 3, 4, 5, 6, 7 };
cout << search_vec(iList.begin(), iList.end(), 3) << endl;
cout << search_vec(iList.begin(), iList.end(), 8) << endl;
return 0;
}
练习9.5
#include <iostream>
#include <vector>
using namespace std;
vector<int>::iterator search_vec(vector<int>::iterator beg,
vector<int>::iterator end, int val)
{
for (; beg != end;beg++)
if (*beg == val)
return beg;
return end;
}
int main()
{
vector<int> iList = { 1, 2, 3, 4, 5, 6, 7 };
cout << search_vec(iList.begin(), iList.end(), 3)- iList.begin()<< endl;
cout << search_vec(iList.begin(), iList.end(), 8) - iList.begin() << endl;
return 0;
}
9.2.2容器类型成员
iterator
迭代器(Iterator)模式,又叫做游标(Cursor)模式。GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。
const_iterator
对象可以用于const vector 或非 const vector,它自身的值可以改(可以指向其他元素),但不能改写其指向的元素值.
size_type
由string类类型和vector类类型定义的类型,用以保存任意string对象或vector对象的长度,标准库类型将size_type定义为unsigned类型
difference_type
是描述序列(容器)中两个元素地址之间差异的有符号整数类型;
value_type
它是一个typedef。是迭代器所指对象的类型
reference
元素的左值类型;与value_type&含义相同
const_reference
元素的const左值类型(即const value_type&)
9.2.3begin和end成员
begin:指向容器中第一个元素。
end:指向容器中最后一个元素的下一位置。
其他版本:
带r的版本返回迭代器,以c开头的版本则返回const迭代器。
#include<iostream>
#include <vector>
#include <list>
#include <deque>
using namespace std;
int main()
{
vector<int> a;
list<int> b;
deque<int> c;
a.push_back(1);
a.push_back(2);
a.push_back(3);
const vector<int> ca(a);
b.push_back(10);
b.push_back(20);
b.push_back(30);
c.push_back(100);
c.push_back(200);
c.push_back(300);
for (vector<int>::size_type i = 0; i < a.size(); ++i)
cout << a[i] << endl;
//for (list<int>::size_type k = 0; k < b.size();++k)
// cout << b[k] << endl;
for (deque<int>::size_type n = 0; n < c.size(); ++n)
cout << c[n] << endl;
vector<int>::iterator firsta = a.begin();
vector<int>::iterator lasta = a.end();
while (firsta != lasta)
{
cout << "迭代器循环:" << endl;
++firsta;
}
vector<int>::reverse_iterator rfirsta = a.rbegin();
vector<int>::reverse_iterator rlasta = a.rend();
vector<int>::const_iterator cfirsta = ca.begin();
vector<int>::const_iterator clasta = ca.end();
//cout << "迭代器:" << *firsta << endl;
//cout << *lasta << endl;
vector<int>::size_type a1;
vector<int>::iterator a2;
vector<int>::const_iterator a3;
vector<int>::reverse_iterator a4;
vector<int>::const_reverse_iterator a5;
vector<int>::difference_type a6;
/*vector<int>::value_type a7;
vector<int>::reference a8;
vector<int>::const_reference a9;*/
list<int>::size_type b1;
list<int>::iterator b2;
list<int>::const_iterator b3;
list<int>::reverse_iterator b4;
list<int>::const_reverse_iterator b5;
list<int>::difference_type b6;
/*list<int>::value_type b7;
list<int>::reference b8;
list<int>::const_reference b9;*/
deque<int>::size_type d1;
deque<int>::iterator d2;
deque<int>::const_iterator d3;
deque<int>::reverse_iterator d4;
deque<int>::const_reverse_iterator d5;
deque<int>::difference_type d6;
/*deque<int>::value_type d7;
deque<int>::reference d8;
deque<int>::const_reference d9;*/
return 0;
}
练习9.9
begin和cbegin两个函数有什么不同?
cbegin是C++新标准引入的,用来与auto结合使用。它返回指向容器第一个元素的const迭代器,可以用来只读地访问容器元素,但不能对容器元素进行修改。因此,当不需要些访问时,应该使用cbegin。
begin则是被重载过的,有两个版本:其中一个是const成员函数,也返回const迭代器;令一个则返回普通迭代器,可以对容器元素进行修改。
9.2.4容器定义和初始化
当将一个容器初始化为另一个容器的拷贝是,两个容器的容器类型和元素类型都必须相同。但当传递迭代器参数来拷贝一个范围时,就不要求容器类型是相同的了。
#include <iostream>
#include <list>
#include <vector>
#include <deque>
#include <string>
using namespace std;
int main()
{
vector<string> svec;//默认的构造函数
svec.push_back("hello");
svec.push_back("C++");
svec.push_back("STL");
list<int> ilist;
vector<int> ivec;//默认的构造函数
ivec.push_back(1);
ivec.push_back(2);
ivec.push_back(3);
vector<int> ivec2(ivec);
//list<int> ilist(ivec);//两个容器类型不同
list<string> slist(svec.begin(), svec.end());
vector<string>::iterator mid = svec.begin() + svec.size() / 2;
deque<string> front(svec.begin(), mid);
deque<string> back(mid, svec.end());
return 0;
}
9.2.5赋值和swap
赋值运算
要求左边和右边的运算对象具有相同的类型。
使用assign(仅顺序容器)
这个函数允许我们从不同的但相容的类型赋值,或者从容器的一个子序列赋值
使用swap
swap操作交换两个相同类型容器的内容。调用swap之后,两个容器中的元素将会交换,但是元素的本身并没未交换,swap只是交换了两个容器的内部数据结构。
//使用assign:类型兼容即可
//使用swap:类型必须相同
#include<iostream>
#include <vector>
#include <string>
#include <list>
using namespace std;
int main()
{
vector<int> a;
vector<int>b;
vector<int>c;
vector<char *> svec;
list<string> slist;
svec.push_back("apple");
svec.push_back("big");
svec.push_back("cat");
slist.push_back("c");
slist.push_back("c++");
slist.push_back("java");
slist.push_back("c#");
//svec.assign(slist.begin(), slist.end());
slist.assign(svec.begin(), svec.end());
for (list<string>::iterator iter = slist.begin();
iter != slist.end(); ++iter)
cout << *iter << endl;
slist.assign(10, "Hiya");
for (list<string>::iterator iter = slist.begin();
iter != slist.end(); ++iter)
cout << *iter << endl;
a.push_back(10);
a.push_back(20);
a.push_back(30);
a.push_back(40);
b.push_back(100);
b.push_back(200);
b.push_back(300);
c.push_back(1);
c.push_back(2);
c.push_back(3);
c.push_back(4);
c.push_back(5);
a.swap(b);
for (vector<int>::iterator iter = a.begin();
iter != a.end(); ++iter)
cout << *iter << endl;
a = b;
for (vector<int>::iterator iter = a.begin();
iter != a.end(); ++iter)
cout << *iter << endl;
vector<int>::iterator f = c.begin();
++f;
vector<int>::iterator e = c.end();
--e;
//a.assign(c.begin(), c.end());
a.assign(f, e);
for (vector<int>::iterator iter = a.begin();
iter != a.end();++iter)
cout << *iter << endl;
return 0;
}
9.2.6容器大小操作
//关系运算符
//所有的容器都可以使用
//比较的容器必须具有相同的容器类型
//容器的计较是基于内元素的比较
//容器内元素必须有相应的关系运算符
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> ivec1;
vector<int> ivec2;
ivec1.push_back(1);
ivec1.push_back(3);
ivec1.push_back(5);
ivec1.push_back(7);
ivec1.push_back(9);
ivec1.push_back(11);
ivec2.push_back(0);
ivec2.push_back(2);
ivec2.push_back(4);
ivec2.push_back(6);
ivec2.push_back(8);
ivec2.push_back(10);
ivec2.push_back(12);
if (ivec1 > ivec2)
cout << "ivec1大!" << endl;
return 0;
}