编写一个Sink迭代器,同时可以完成inserter迭代器和打印数值的功能
本周的作业如上面所示了。要求是编写一个迭代器,将默认的inserter迭代器的功能实现,并且在每次迭代的时候能够把容器内的数据打印出来。
既然如此,那我们就把inserter改一改吧。
//sink.h
#include <iostream>
#include <iterator>
template <class Container>
class sink_iterator {
public:
typedef std::output_iterator_tag iterator_category;
typedef typename Container::value_type value_type;
typedef typename Container::difference_type difference_type;
typedef typename Container::pointer pointer;
typedef typename Container::reference reference;
protected:
Container* container;
typename Container::iterator iter;
public:
sink_iterator(Container &x, typename Container::iterator i):container(&x), iter(i) {};
sink_iterator<Container>& operator= (const typename Container::value_type& value) {
iter = container->insert(iter, value);
++iter;
std::cout << value << " ";
return *this;
}
};
这样就把inserter的迭代器给写好了,不过还差一个辅助函数用来调用sink_iterator。那就是sink本函。
template <class Container, class Iterator>
inline sink_iterator<Container> sink(Container& x, Iterator i) {
typedef typename Container::iterator iter;
return sink_iterator<Container>(x, iter(i));
};
这样做好之后,我用如下的测试代码进行测试。
//main.cpp
#include <iostream>
#include <vector>
#include <list>
#include "sink.h"
int main() {
int myints[] = {10,20,30,40,50,60,70};
std::vector<int> myvec(7);
std::copy(myints, myints+7, myvec.begin());
for(auto& i: myvec)
std::cout << i << " ";
std::cout << std::endl;
std::list<int> foo, bar;
for(int i=1;i<=5;i++) {
foo.push_back(i); bar.push_back(i*10);
}
auto it = foo.begin();
std::advance(it, 3);
std::copy(bar.begin(),bar.end(),sink(foo,it));
return 0;
}
编译的时候,却提示我。
C:/PROGRA~1/MINGW-~1/X86_64~1.0-P/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/stl_algobase.h:293:30: error: no match for 'operator++' (operand type is 'sink_iterator<std::__cxx11::list<int> >')
for (; __first != __last; ++__result, (void)++__first)
^~~~~~~~~~
C:/PROGRA~1/MINGW-~1/X86_64~1.0-P/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/stl_algobase.h:294:6: error: no match for 'operator*' (operand type is 'sink_iterator<std::__cxx11::list<int> >')
*__result = *__first;
^~~~~~~~~
看来想偷懒只写出operator=
是不行的。还需要对operator++
和operator*
操作符进行实现。
#include <iostream>
#include <iterator>
template <class Container>
class sink_iterator {
public:
typedef std::output_iterator_tag iterator_category;
typedef typename Container::value_type value_type;
typedef typename Container::difference_type difference_type;
typedef typename Container::pointer pointer;
typedef typename Container::reference reference;
protected:
Container* container;
typename Container::iterator iter;
public:
sink_iterator(Container &x, typename Container::iterator i):container(&x), iter(i) {};
sink_iterator<Container>& operator= (const typename Container::value_type& value) {
iter = container->insert(iter, value);
++iter;
std::cout << value << " ";
return *this;
}
sink_iterator<Container>& operator++ () {
++iter;
return *this;
}
sink_iterator<Container>& operator*() {
return *this;
}
};
template <class Container, class Iterator>
inline sink_iterator<Container> sink(Container& x, Iterator i) {
typedef typename Container::iterator iter;
return sink_iterator<Container>(x, iter(i));
};
然后再进行编译就调试通过了。
程序运行结果是:
10 20 30 40 50 60 70
10 20 30 40 50
与预期结果完全一致。