在C++语言中,有一些诸如数组、string、流和 bitset 虽然说并非属于标准STL,但在某种程度上与 STL 相关。以下就简单介绍一下。
我们知道,“哑”指针可以很好的作为迭代器,因为它们支持所需的操作符。这一点绝非小事,这说明你可以把常规的C++数组当作 STL 容器,自学使用元素的指针作为迭代器。当然,数组并没有提供诸如 size ( ) 、empty ( ) 、insert ( ) 和 erase ( ) 等方法,因此它们不是真正意义上的容器。不过,数组通过指针确实支持迭代器,通过以下一个小例子简单看一下即可。
#include<vector> #include<iostream> using namespace std; int main() { int arr[10];//normal C++ array vector<int> vec;//STL vector //initialize each element of they array to the value of its index for(int i = 0; i < 10; i++) { arr[i] = i; } //insert the contents of the array into the end of the vector vec.insert(vec.end(), arr, arr+10); //print the contents of the vector for(i = 0; i < 10; i++) { cout << vec[i] <<" "; } return 0; }
可以把 string 看作是字符的一个顺序容器。它包括 begin( ) 和 end( ) 方法(会返回指向 string 内部的迭代器)、insert( ) 和 erase( ) 方法、size( ) 、empty( ),以及所有其他顺序容器的基本功能。这与 vector 相当接近,甚至还提供了 reserve( ) 和 capacity( ) 方法。不过,不同于 vector ,string 不需要将元素连续地存储在内存中。另外 vector 提供的某些方法 string 并没有提供,如 push_back( )。例如:
#include<string> #include<iostream> using namespace std; int main() { string str; str.insert(str.end(),'h'); str.insert(str.end(),'e'); str.insert(str.end(),'l'); str.insert(str.end(),'l'); str.insert(str.end(),'0'); for(string::const_iterator it = str.begin(); it !=str.end(); it++) { cout << *it; } cout << endl; return 0; }
从传统意义上讲,输入和输出流并不是容器,它们不存储元素。不过,可以把流考虑成元素序列,因此与 STL 容器有一些共同的特性。 C++ 流没有直接提供任何与STL相关的方法,但是 STL 提供了一些特殊的迭代器,名为 istream_iterator 和 outstream_iterator ,由此可以“迭代”处理输入和输出流。使用这些迭代器,就可以对输入和输出流进行适配,这样输入和输出流就可以在各种STL算法中分别用作源和目标。例如,可以使用 ostream_iterator 利用 copy ( ) 算法打印出一个容器中的元素,这只需一行代码:
#include<algorithm> #include<iostream> #include<iterator> #include<vector> using namespace std; int main() { vector<int> myVector; for(int i= 0; i < 10; i++) myVector.push_back(i); //print the contents of the vector copy(myVector.begin(), myVector.end(), ostream_iterator<int>(cout, " ")); cout<<endl; return 0; }
类似地,可以使用迭代器抽象利用 istream_iterator 从一个输入流读取值。istream_iterator 可以在算法和容器方法中用作源。它不如 ostream_iterator 那么常用,所有在这里就不再提供输入流迭代器的例子。
bitset 是位序列的一个定长抽象。一位表示两个值,通常表示为 1 和 0 、开和关、true 和 false 。bitset 也使用术语设置(set)和反设置(unset)。可以对一位触发(toggle)或取反(flip),使之从一个值变为另一个值。
bitset 并不是真正的STL容器,它是定长的,并非对元素类型模板化,而且不支持迭代。不过,这是一个很有用的工具,经常与容器一起使用,所以有必要了解一下 bitset 。
bitset 在 <bitset> 头文件中定义,它基于所存储的位数来实现模板化。默认构造函数会把 bitset 的所有位域初始化为 0.另外一个构造函数可以从一个由 0 和 1 组成的 string 创建 bitset 。
可以用 set( )、reset( ) 和 flip( ) 方法调整单个位的值,可以用一个重载的 operator[ ] 访问和设置 bitset 的位域。需要注意,在一个非 const 对象上调用 operator [ ] 会返回一个代理对象,可以对其赋一个布尔值、调用 flip( ) ,或者用 ~ 取反。还可以用 test( ) 方法访问单个的位域。
另外,可以用常规的流插入和析取操作符完成 bitset 的流输入和输出。bitset 会作为包括 0 和 1 的字符串流入流出。
以下是一个小例子。
#include<bitset> #include<iostream> using namespace std; int main() { bitset<10> myBitset; myBitset.set(3); myBitset.set(6); myBitset[8] = true; myBitset[9] = myBitset[3]; if(myBitset.test(3)) { cout<<"Bit 3 is set!"<<endl; } cout << myBitset <<endl; return 0; }
输出为:
tips:输出 string 中最左字符是最高编号位(即编号或索引为 9)。
除了基本位处理例程,bitset 还提供了所有为操作符的实现:&、|、^、~、<<、>>、&=、|=、^=、<<= 和 >>=。这些操作符表现得就好像在“真的”位序列上操作一样。以下是一个例子。
#include<bitset> #include<iostream> using namespace std; int main() { string str1 = "0011001100"; string str2 = "0000111100"; bitset<10> bitsOne(str1),bitsTwo(str2); bitset<10> bitsThree = bitsOne & bitsTwo; cout << bitsThree <<endl; bitsThree <<= 4; cout << bitsThree << endl; return 0; }
没了。