template// move iter d units
void advance(IterT& iter, DistT d); // forward; if d < 0,
// move iter backward
struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag: public input_iterator_tag {};
struct bidirectional_iterator_tag: public forward_iterator_tag {};
struct random_access_iterator_tag: public bidirectional_iterator_tag {};
template
void advance(IterT& iter, DistT d)
{
if (iter is a random access iterator) {
iter += d; // use iterator arithmetic
} // for random access iters
else {
if (d >= 0) { while (d--) ++iter; } // use iterative calls to
else { while (d++) --iter; } // ++ or -- for other
} // iterator categories
}
template// template for information about
struct iterator_traits; // iterator types
template < ... >// template params elided
class deque {
public:
class iterator {
public:
typedef random_access_iterator_tag iterator_category;
...
};
...
};
template < ... >
class list {
public:
class iterator {
public:
typedef bidirectional_iterator_tag iterator_category;
...
};
...
};
// the iterator_category for type IterT is whatever IterT says it is;
// see Item 42 for info on the use of "typedef typename"
template
struct iterator_traits {
typedef typename IterT::iterator_category iterator_category;
...
};
template// partial template specialization
struct iterator_traits// for built-in pointer types
{
typedef random_access_iterator_tag iterator_category;
...
};
template
void advance(IterT& iter, DistT d)
{
if (typeid(typename std::iterator_traits::iterator_category) ==
typeid(std::random_access_iterator_tag))
...
}
template// use this impl for
void doAdvance(IterT& iter, DistT d, // random access
std::random_access_iterator_tag) // iterators
{
iter += d;
}
template// use this impl for
void doAdvance(IterT& iter, DistT d, // bidirectional
std::bidirectional_iterator_tag) // iterators
{
if (d >= 0) { while (d--) ++iter; }
else { while (d++) --iter; }
}
template// use this impl for
void doAdvance(IterT& iter, DistT d, // input iterators
std::input_iterator_tag)
{
if (d < 0 ) {
throw std::out_of_range("Negative distance"); // see below
}
while (d--) ++iter;
}
template
void advance(IterT& iter, DistT d)
{
doAdvance( // call the version
iter, d, // of doAdvance
typename // that is
std::iterator_traits::iterator_category() // apPRopriate for
); // iter's iterator
} // category
新闻热点
疑难解答