迭代器可以区分不同类型,每个类型都代表特定的迭代器能力。
如果能根据不同的迭代器种类将操作行为重载,将会很有用,甚至很必要.
通过迭代器标志和特性可以实现这样的重载
这里用到了继承,可说任何forward迭代器都是一种input迭代器
rug
C++标准库提供了一种特殊的template结构来定义所谓的迭代器特性,该结构包含迭代器相关的所有信息,如:
在这个template中 _Iter表示迭代器类型。有了它,我们就可以撰写任何"运用迭代器种类或其元素类型"的泛型码.
针对指针还有特化版本如下:
为迭代器编写泛型函数
借由迭代器特性,你能写出根据迭代器种类而用不同的实现代码的函数
使用value_type
例子如下:
template <typename ForwardIterator>
void shift_left(ForwardIterator beg, ForwardIterator end)
{
using value_type = typename std::iterator_traits<ForwardIterator>::value_type;
if (beg != end)
{
value_type tmp(*beg);
....
}
}
自定义迭代器
自己写的迭代器,必须让iterator trait能够处理这样的迭代器.两种办法可行:
1.提供必要的五种类型定义,就像iterator_traits
2.为iterator_traits结构提供一个特化版本
下面是一个实例:
template <typename Container>
class asso_insert_iterator :public std::iterator<output_iterator_tag, typename Container::value_type>
{
protected:
Container& container;
public:
explicit asso_insert_iterator(Container & c) : container(c)
{
}
asso_insert_iterator<Container>& operator=(const typename Container::value_type&value)
{
container.insert(value);
return *this;
}
asso_insert_iterator<Container>& operator*()
{
return *this;
}
asso_insert_iterator<Container>& operator++()
{
return *this;
}
asso_insert_iterator<Container>& operator++(int)
{
return *this;
}
};
template<typename Container>
inline asso_insert_iterator<Container> asso_inserter(Container& c)
{
return asso_insert_iterator<Container>(c);
}
template<typename T>
inline void PRINT_ELEMENTS(const T & coll, const std::string & optstr = "")
{
std::cout << optstr;
for (const auto & elem : coll)
{
std::cout << elem << ' ';
}
std::cout << std::endl;
}
int main()
{
unordered_set<int>coll;
asso_insert_iterator<decltype(coll)>iter(coll);
*iter = 1;
iter++;
*iter = 2;
iter++;
*iter = 3;
PRINT_ELEMENTS(coll);
asso_inserter(coll) = 44;
asso_inserter(coll) = 55;
PRINT_ELEMENTS(coll);
}