简而言之:标签用于重载,用于优化。
举个简单advance
的例子,你可能会设计:
template<class II, class D>
void advance(II& i, D n){
while( n-- ) ++i;
}
但是它具有O(n)
复杂性,当您拥有random_access_iterator
. 所以你可以像这样改变你的设计:
template<class II, class D>
void advance_II(II& i, D n){
while( n-- ) ++i;
}
template<class RAI, class D>
void advance_RAI(RAI& i, D n){
i += n;
}
template<class II, class D>
void advance(II& i, D n){
if(is_random_access_iterator(i)) // not yet designed
advance_RAI(i, n);
else
advance_II(i, n);
}
但是要使用的函数版本是在运行时决定的,所以我们尽量让编译器在编译时决定选择哪种方法。所以我们给迭代器标签。有五个标签:
struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag : public input_iterator_tag {};
struct bidirection_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirection_iterator_tag {};
现在你可以这样做:
template<class II, class D>
void __advance(II& i, D n, input_iterator_tag){
while( n-- ) ++i;
}
template<class RAI, class D>
void __advance(RAI& i, D n, random_access_iterator_tag){
i += n;
}
template<class II, class D>
void advance(II& i, D n){
__advance(i, n, iterator_traits<II>::iterator_category());
}