STL与泛型编程<一>:容器的共通能力和共通操作
容器的共通能力
所有的STL都必须满足一些共同的条件,三个最核心的能力是
1. “所有容器提供的都是”value语意”而非”reference语意”。这意味着STL容器所容纳的是你所安插的对象值,若要实现reference语意,可以让容器容纳指针
2. 总体而言,所有元素形成一个次序。每个容器都提供了“可返回迭代器”的函数
3. 一般而言,各项操作绝非安全,STL追求的是效率!
容器的共通操作
见下表为容器类别(Container Classes)的共通操作函数
可看出分为四类:初始化、与大小相关的操作函数、比较
初始化
每个容器类别都提供了一个default构造函数,一个copy构造函数,一个析构函数。这些构造函数都是member template,所以提供了从“来源端”到“目标端”的元素自动型别转换。
下面看一个例子(以某个数组的元素值为处值)对这些函数进行测试
#include <iostream>
#include <vector>
using namespace std;
void print(vector<int> v1);
int main(void)
{
int arr1[] = {1,2,3};
vector<int> v1(arr1,arr1+sizeof(arr1)/sizeof(arr1[0]));
vector<int> v2(v1);
print(v1);
cout << endl;
print(v2);
return 0;
}
void print(vector<int> v1)
{
vector<int>::const_iterator it = v1.begin();
for (; it!=v1.end(); ++it)
{
cout << *it << " ";
}
}
以标准输入装置完成初始化操作
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;
void print(vector<int> v1);
int main(void)
{
vector<int> v1((istream_iterator<int>(cin)), (istream_iterator<int //定义一个容器,容器的内容从标准输入获取
print(v1);
return 0;
}
void print(vector<int> v1)
{
vector<int>::const_iterator it = v1.begin();
for (; it!=v1.end(); ++it)
{
cout << *it << " ";
}
}
/*
1.不要忘了那对多余的括号(程序注释处),若忘记了,编译器会把之当做函数来看待的
2. 运行成功后,我输入a,d,f并按下回车没反应,原来元素定义的是int
测试数据如下:
1.输入12sdd45,按下回车输出12
2.输入ssd45,按下回车输出空
3.输入345,按下回车没有结束,需要按Ctrl+z才行
4.输入345,按下回车没有结束,载输入6,需要按Ctrl+z后,显示
345 6
*/
与大小相关的函数
见下面的程序
#include <iostream>
#include <vector>
using namespace std;
int main(void)
{
int arr1[] = {1,2,3};
vector<int> v1(arr1,arr1+sizeof(arr1)/sizeof(arr1[0]));
cout << "size():" << v1.size() << endl;
cout << "max_size():" << v1.max_size() << endl;
return 0;
}
/*
输出结果:
size():3
max_size():4611686018427387903 很大,和各自平台实现有关
*/
比较
见下面代码
#include <iostream>
#include <vector>
using namespace std;
int main(void)
{
int arr1[] = {1,2,3};
int arr2[] = {3,4,5};
vector<int> v1(arr1,arr1+sizeof(arr1)/sizeof(arr1[0]));
vector<int> v2(arr2,arr2+sizeof(arr2)/sizeof(arr2[0]));
if (v1 == v2)
cout << "v1 == v2";
else if (v1 > v2)
cout << "v1 > v2";
else if (v1 < v2)
cout << "v1 < v2";
return 0;
}
赋值和swap()
当你最着容器赋值元素时,目标容器的原本元素全被移除,所以,容器的赋值操作代价比较高;但如果两个容器类型一样,而且拷贝后源容器不再使用,那么可以使用swap(),swap()性能比上诉优异,因为它只交换容器内部的元素(实际上只交换指针),所以时间复杂度是常数,而不想赋值操作,时间复杂度为线性。见栗子
#include <iostream>
#include <vector>
using namespace std;
void print(vector<int> v1)
{
vector<int>::const_iterator it = v1.begin();
for (; it!=v1.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
}
int main(void)
{
int arr1[] = {1,2,3};
int arr2[] = {3,4,5,6};
vector<int> v1(arr1,arr1+sizeof(arr1)/sizeof(arr1[0]));
vector<int> v2(arr2,arr2+sizeof(arr2)/sizeof(arr2[0]));
cout << "before swap:" << endl;
print(v1);
print(v2);
cout << "after swap:" << endl;
swap(v1,v2);
print(v1);
print(v2);
return 0;
}