STL是Standard Template Labray的简称,它是C++语言的一种扩展。我想学STL,主要是因为最近看了一些源代码,里面很多STL的东西,让我比较头疼,于是乎开始了这一系列。
什么是STL呢?STL就是Standard Template Library,标准模板库。这可能是一个历史上最令人兴奋的工具的最无聊的术语。从根本上说,STL是一些“容器”的集合,这些“容器”有list,vector,set,map等,STL也是算法和其他一些组件的集合。这里的“容器”和算法的集合指的是世界上很多聪明人很多年的杰作。
STL的目的是标准化组件,这样你就不用重新开发它们了。你可以仅仅使用这些现成的组件。STL现在是C++的一部分,因此不用额外安装什麽。它被内建在你的编译器之内。因为STL的list是一个简单的容器,所以我打算从它开始介绍STL如何使用。如果你懂得了这个概念,其他的就都没有问题了。
一、指针迭代器
/**指针迭代器**/
#include <iostream>
#include <algorithm>
using namespace std;
#define SIZE 100
int iarray[SIZE];
int main()
{
iarray[20] = 50;
int *ip = find(iarray, iarray + SIZE, 50);
if ( ip == iarray + SIZE)
cout << "50 not found in array" << endl;
else
cout << *ip << " found in array" << endl;
return 0;
}
结果:50 found in array
find()函数接受三个参数。头两个定义了搜索的范围。由于C和C++数组等同于指针,表达式iarray指向数组的第一个元素。而第二个参数iarray + SIZE等同于past-the-end 值,也就是数组中最后一个元素的后面位置。第三个参数是待定位的值,也就是50。find()函数返回和前两个参数相同类型的迭代器,这儿是一个指向整数的指针ip。
二、容器迭代器
/*容器迭代器*/
#include "stdafx.h"
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
vector<int> intVector(100); //矢量容器
int main(int argc, char* argv[])
{
intVector[20] = 50;
//使用了两个典型的容器方法begin()和end()
vector<int>::iterator intIter = find(intVector.begin(), intVector.end(), 50);
if(intIter != intVector.end())
//显示搜索到的数据
cout << "Vector contains value " << *intIter << endl;
else
cout << "Vector does not contain 50" << endl;
return 0;
}
结果:Vector contains value 50
三、输出迭代器
/*输出迭代器*/
#include "stdafx.h"
#include <iostream>
#include <algorithm> //Need copy()
#include <vector> //Need vector
using namespace std;
double darray[10] = {1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9};
vector<double> vdouble(10);
int main(int argc, char* argv[])
{
vector<double>::iterator outputIterator = vdouble.begin();
//使用copy()算法的时候,必须确保目标容器有足够大的空间,或者容器本身是自动扩展的
copy(darray, darray + 10, outputIterator);
while ( outputIterator != vdouble.end())
{
cout << *outputIterator << endl;
outputIterator++;
}
return 0;
}
结果:
1
1.1
...
1.9
四、输出流迭代器
/*输出流迭代器*/
#include "stdafx.h"
#include <iostream>
#include <cstdlib> //Need rand(), srand()
#include <ctime> //Need time()
#include <algorithm> //Need sort(), copy()
#include <vector> //Need vector
#include <iterator> //Need ostream_iterator
using namespace std;
void Display(vector<int>& v, const char* s);
int main(int argc, char* argv[])
{
// Seed the random number generator
srand(time(NULL));
// Construct vector and fill with random interger values
vector<int> collection(10);
for( int i = 0; i < 10; i++)
collection[i] = rand() % 100;
// Display, sort, and redisplay
Display(collection, "Before sorting");
sort(collection.begin(), collection.end());
Display(collection, "After sorting");
return 0;
}
// Display label s and contents of integer vector v
// 函数Display()显示了如何使用一个输出流迭代器
void Display(vector<int>& v, const char* s)
{
cout << endl << s << endl;
copy(v.begin(), v.end(), ostream_iterator<int>(cout, "\t"));
cout << endl;
}
结果:略
注意ostream_iterator在iterator中,一开始没有,错了!!
STL提供了模板类ostream_iterator。这个类的构造函数有两个参数:一个ostream对象和一个string值。因此可以象下面一样简单地创建一个迭代器对象
ostream_iterator<int>(cout, "\n")
五、插入迭代器
/*插入迭代器*/
//插入迭代器用于将值插入到容器中。它们也叫做适配器,因为它们将容器适配或转化为一个迭代器
#include "stdafx.h"
#include <iostream>
#include <list> //Need list
#include <iterator> //ostream_iterator,inserter
#include <algorithm> //find(), copy()
using namespace std;
int iArray[5] = {1, 2, 3, 4, 5};
void Display(list<int>& v, const char* s);
int main(int argc, char* argv[])
{
//定义一个链表
list<int> iList;
// Copy iArray backwards into iList
// Front inserters 将对象插入到数据集的前面——例如,链表表头。
copy(iArray, iArray + 5, front_inserter(iList));
Display(iList, "Before find and copy");
// Locate value 3 in iList
list<int>::iterator p = find(iList.begin(), iList.end(), 3);
// Copy first two iArray values to iList ahead of p
copy(iArray, iArray + 2, inserter(iList, p));
Display(iList, "After find and copy");
return 0;
}
void Display(list<int>& a, const char* s)
{
cout << s << endl;
copy(a.begin(), a.end(), ostream_iterator<int>(cout, " "));
cout << endl;
}
六、函数和断言
// 函数和断言.cpp : 定义控制台应用程序的入口点。
/*
*STL中,函数被称为算法,也就是说它们和标准C库函数相比,它们更为通用。
*STL算法通过重载operator()函数实现为模板类或模板函数。
*这些类用于创建函数对象,对容器中的数据进行各种各样的操作。
*/
#include "stdafx.h"
#include <iostream>
#include <cstdlib> //Need rand(), srand()
#include <ctime> //Need time()
#include <vector> //Need vector
#include <algorithm> //Need for_each(),find_if
using namespace std;
#define VSIZE 24 //Size of vector
//矢量对象
vector<long> v(VSIZE); //Vector object
//Function prototypes
void initialize(long &ri);
void show(const long &ri);
bool isMinus(const long &ri); // Predicate function
int main(int argc, char* argv[])
{
//Seed random generator
srand(unsigned(time(NULL)));
//调用普通函数initialize
for_each(v.begin(), v.end(), initialize);
cout << "Vector of signed long integers" << endl;
for_each(v.begin(), v.end(), show);
cout << endl;
// Use predicate function to count negetive values
int count = 0;
vector<long>::iterator p;
p = find_if(v.begin(), v.end(), isMinus); //调用断言函数
while (p != v.end())
{
count++;
p = find_if(p + 1, v.end(), isMinus);
}
cout << "Number of values: " << VSIZE << endl;
cout << "Negative values : " << count << endl;
return 0;
}
// Set ri to a signed integer value
void initialize(long &ri)
{
ri = (rand() - (RAND_MAX/2));
}
// Display value of ri
void show(const long &ri)
{
cout << ri << " ";
}
// Returns true if ri is less than 0
bool isMinus(const long &ri)
{
return (ri < 0);
}
参考:
3.走近 STL