<iterator>
1 种类标签 Category tags
input/output/forward/bidirectional/random_access _iterator_tag
—————————————————————————————————————————————————————————————————————————————————————————————————————————————
input `只可解引用为 rvalue` *a / a->m
—————————————————————————————————————————————————————————————————————————
output mutable iterator 可解引用为 lvalue *iter++ = t
forward —————————————————————————————————————————————————————————————————————————
`默认构造` X iter
bidirectional —————————————————————————————————————————————————————————————————————————————————————
--
—————————————————————————————————————————————————————————————————————————————————————————————————————
random_access iter1 + n / iter1 - n / iter1 - iter2 / iter +=/-= n
比较 < > <= >=
`下标` iter[n]
—————————————————————————————————————————————————————————————————————————————————————————————————————————————
2 函数
(1) 迭代器操作
[1] `std::distance(inputIter1, inputIter2)`
`从 inputIter1 到 inputIter2 要正向走的步数: 正/负 n`
template<class InputIterator>
typename iterator_traits<InputIterator>::difference_type
distance (InputIterator first, InputIterator last);
可 正/负整数
[2] `std::advance(inputIter, n)`
`将 iter 前移 n(可 < 0) 个 elemPos`
if iter 随机
operator+/-(n)
else
n 次 operator++/--
template <class InputIterator, class Distance>
void
advance (InputIterator& it, Distance n);
[3] begin()
|
end()
(2) 迭代器生成器
[1] `back_inserter(container)`
|
front_inserter(container)
返回 `后插迭代器`, 可 `在容器后插新元素`
template <class Container>
back_insert_iterator<Container>
back_inserter (Container& c);
// eg
std::vector<int> foo, bar;
for (int i=1; i<=5; i++)
{
foo.push_back(i);
bar.push_back(i*10);
}
std::copy (bar.begin(), bar.end(), back_inserter(foo) ); // => foo: 1 2 3 4 5 10 20 30 40 50
[2] `inserter(container, containerIter)`
template <class Container>
insert_iterator<Container>
inserter (Container& x, typename Container::iterator it);
#include <iostream>
#include <iterator> // std::inserter, std::advance
#include <list> // std::list
#include <algorithm> // std::copy
int main ()
{
std::list<int> foo, bar;
for (int i=1; i<=5; i++)
{
foo.push_back(i);
bar.push_back(i*10);
}
std::list<int>::iterator it = foo.begin();
advance (it,3);
std::copy (bar.begin(),bar.end(),std::inserter(foo,it) ); // 1 2 3 10 20 30 40 50 4 5
}
3 类
(1) iterator<IterCategory, T>: 5 种关联型别
给 iterator_traits用于萃取出想要萃取的型别给client
template <class Category, // `迭代器种类`
class T, // 所指 `元素类型`
class Distance = ptrdiff_t, // <cstddef> `两指针相减` 的有符号(可 `正/负` ) 整数类型
class Pointer = T*,
class Reference = T&>
struct iterator
{
typedef T value_type;
typedef Distance difference_type;
typedef Pointer pointer;
typedef Reference reference;
typedef Category iterator_category;
};
`自定义迭代器: 要继承自 std::iterator`
#include <iterator>
class MyIterator : public std::iterator<std::input_iterator_tag, int>
{
private:
int* p;
public:
MyIterator(int* x) :p(x) {}
MyIterator(const MyIterator& mit) : p(mit.p) {}
MyIterator& operator++() {++p;return *this;}
MyIterator operator++(int) {MyIterator tmp(*this); operator++(); return tmp;}
bool operator==(const MyIterator& rhs) const {return p==rhs.p;}
bool operator!=(const MyIterator& rhs) const {return p!=rhs.p;}
int& operator*() {return *p;}
};
(2) `iterator_traits<Iterator>`
template <class Iterator>
class iterator_traits;
template <class T>
class iterator_traits<T*>;
template <class T>
class iterator_traits<const T*>;
template <class Iterator>
struct iterator_traits
{
typedef typename Iterator::iterator_category iterator_category;
typedef typename Iterator::value_type value_type;
typedef typename Iterator::difference_type difference_type;
typedef typename Iterator::pointer pointer;
typedef typename Iterator::reference reference;
};
template <class T>
struct iterator_traits<T*>
{
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef T& reference;
};
4 取迭代器3种关联型别
的函数模板: 旧STL 自带, 新 STL 可据旧STL 自定义
// iteratorHelperFunc.h
#pragma
#include <iterator>
template <class Iterator>
inline typename std::iterator_traits<Iterator>::iterator_category
iteratorCategory(const Iterator&)
{
typename std::iterator_traits<Iterator>::iterator_category iterCategory;
return iterCategory();
}
template <class Iterator>
inline typename std::iterator_traits<Iterator>::value_type*
valuePtrType(const Iterator&)
{
return static_cast<typename std::iterator_traits<Iterator>::value_type*>(0);
}
template <class Iterator>
inline typename std::iterator_traits<Iterator>::difference_type*
differencePtrType(const Iterator&)
{
return static_cast<typename std::iterator_traits<Iterator>::difference_type*>(0);
}
// test.cpp
#include "iteratorHelperFunc.h"
#include <list>
#include <iostream>
template<class BidirectionalIter, class ValueType>
void f1(BidirectionalIter first, BidirectionalIter last, ValueType*)
{
ValueType value = *first;
std::cout << value << std::endl; // 5
}
template<class BidirectionalIter, class DifferenceType>
void f2(BidirectionalIter first, BidirectionalIter last, DifferenceType*)
{
DifferenceType d = std::distance(first, last);
std::cout << d << std::endl; // 1
}
int main()
{
std::list<int> lst;
lst.push_back(5);
using Iter = std::list<int>::iterator;
Iter first = lst.begin();
Iter last = lst.end();
f1(first, last, valuePtrType(first) );
f2(first, last, differencePtrType(first) );
}
Note const_iterator
类型
对容器内元素 `只读`
`解引用` 得 `const (对象的) 引用`
5 输出/入流迭代器
ostream_iterator 需要知道所要打印的对象类型
template <class T, // T: 所要输出的对象类型
class charT=char,
class traits=char_traits<charT> >
class ostream_iterator;
// Ctor: 第2参数为分隔符
ostream_iterator (ostream_type& s
[,const char_type* delimiter]);
transform(stringPtrSet.begin(), stringPtrSet.end(),
ostream_iterator<string>(std::cout, "\n"), // 输出区间迭代器
Dereference() );
template<class T, // T: 所要输入的对象类型
...>
class istream_iterator;
// Ctor:
istream_iterator(); // 默认 Ctor: end-of-stream iterator
istream_iterator (istream_type& s); // 输入流 iterator
int main()
{
std::istream_iterator<double> eos; // end-of-stream iterator
std::istream_iterator<double> iit (std::cin); // stdin iterator
if (iit != eos)
value1=*iit;
++iit;
if (iit != eos)
value2=*iit;
std::cout << (value1*value2) << '\n';
}
网友评论