《stl源码剖析》:仿函数、配接器
证同元素 identity_element。相当于代数里面的单位元。identity_element函数不是STL标准一员,但很多STL都会实现。
间接性是抽象化的重要工具。
三种Insert iterator迭代器:
back_inserter:安插于容器最尾端,back_inserter内部调用push_back() 因此需要容器支持push_back()操作,这样的容器有三个:vector deque list
front_inserter: 安插于容器最前端,需要容器支持push_front()操作,这样的容器只有deque和list
inserter:一般型安插迭代器,它将元素插入迭代器初始化时传入的第二参数所指位置的前方。Inserters内部调用Insert()成员函数,因此支持所有的STL容器。也是唯一可用于关联式容器的安 插迭代器。
其实上面三个是辅助函数,真正调用的是对应的三种迭代器适配器:
// TEMPLATE CLASS back_insert_iterator
template<class _Container>
class back_insert_iterator
: public _Outit
{
// wrap pushes to back of container as output iterator
public:
typedef _Container container_type;
typedef typename _Container::reference reference;
typedef _Range_checked_iterator_tag _Checked_iterator_category;
explicit back_insert_iterator(_Container &_Cont)
: container(&_Cont)
{
// construct with container
}
back_insert_iterator<_Container> &operator=(
typename _Container::const_reference _Val)
{
// push value into container
container->push_back(_Val);
return (*this);
}
back_insert_iterator<_Container> &operator*()
{
// pretend to return designated value
return (*this);
}
back_insert_iterator<_Container> &operator++()
{
// pretend to preincrement
return (*this);
}
back_insert_iterator<_Container> operator++(int)
{
// pretend to postincrement
return (*this);
}
protected:
_Container *container; // pointer to container
};
// TEMPLATE FUNCTION back_inserter
template<class _Container> inline
back_insert_iterator<_Container> back_inserter(_Container &_Cont)
{
// return a back_insert_iterator
return (std::back_insert_iterator<_Container>(_Cont));
}
注意上面back_insert_iterator中重载操作符operator=,正是它通过调用容器的push_back()实现真正的插入操作。
类似的,另外两个辅助函数真正调用的迭代器适配器语句为:
return (front_insert_iterator<_Container>(_Cont));
return (insert_iterator<_Container>(x,iter(i)));
Reverse Iterators(逆向迭代器):
逆向迭代器用逆向的方式对容器进行所有操作,它将递增运算转换成递减。通过它完成对容器的倒序操作。所有容器都可以通过rbegin()和rend()产生reverse iterators。
通过逆向迭代器的base()函数可以将逆向迭代器转换成正常迭代器。
看Reverse Iterators的源码,它以一个iterator为成员,所有的操作对是针对该iterator成员进行的。只要掌握逆向迭代器的意义(所关联的正向迭代器后退一格),这些操作的代码很容易实现出来。
看stream iterator的代码很有启发作用,可以参考它们自己量身定制一个迭代器。
STL容器只支持“实值语意”(value semantic),不支持“引用语意”(reference semantics),因此下面这样的无法通过编译:
vector<Shape&> v;
vector<Shape&> v;