先来看一段代码:
using std::iterator_traits;
using std::iterator;
template<typename _Iterator, typename _Container>
class __normal_iterator
{
protected:
_Iterator _M_current;
public:
typedef _Iterator iterator_type;
typedef typename iterator_traits<_Iterator>::iterator_category
iterator_category;
typedef typename iterator_traits<_Iterator>::value_type value_type;
typedef typename iterator_traits<_Iterator>::difference_type
difference_type;
typedef typename iterator_traits<_Iterator>::reference reference;
typedef typename iterator_traits<_Iterator>::pointer pointer;
__normal_iterator() : _M_current(_Iterator()) { }
explicit
__normal_iterator(const _Iterator& __i) : _M_current(__i) { }
// ..... ........ .. .............. ..........
template<typename _Iter>
__normal_iterator(const __normal_iterator<_Iter,
typename __enable_if<
(std::__are_same<_Iter, typename _Container::pointer>::__value),
_Container>::__type>& __i)
: _M_current(__i.base()) { }
// ....... ........ ............
reference
operator*() const
{ return *_M_current; }
pointer
operator->() const
{ return _M_current; }
__normal_iterator&
operator++()
{
++_M_current;
return *this;
}
__normal_iterator
operator++(int)
{ return __normal_iterator(_M_current++); }
// ............. ........ ............
__normal_iterator&
operator--()
{
--_M_current;
return *this;
}
__normal_iterator
operator--(int)
{ return __normal_iterator(_M_current--); }
// ...... ...... ........ ............
reference
operator[](const difference_type& __n) const
{ return _M_current[__n]; }
__normal_iterator&
operator+=(const difference_type& __n)
{ _M_current += __n; return *this; }
__normal_iterator
operator+(const difference_type& __n) const
{ return __normal_iterator(_M_current + __n); }
__normal_iterator&
operator-=(const difference_type& __n)
{ _M_current -= __n; return *this; }
__normal_iterator
operator-(const difference_type& __n) const
{ return __normal_iterator(_M_current - __n); }
const _Iterator&
base() const
{ return _M_current; }
};
这是一段从STL摘录的代码。这个模板做了啥?它把所有的操作原样传给了传进来的_Iterator,因为是简单内联,编译之后就像什么都没写一样!好像是皇帝的新装。要说什么都没做,又不完全是这样。因为C++是支持多态的语言。当一个传进来的类型,在模板中使用,产生编译错误时,由于各种组合的可能性,编译器会报大量的让人费解的错误。让这个类型先传给一个什么也不做的"空"模板,那么就可以把编译错误拦截下来,在"空"模板里先报错。这是个一一映射,这个错误信息就会清楚的多。
所以一个看起来什么也不做的模板,可以在编译期间做额外的类型检查,并且使编译器产生的错误信息更易懂。