I’m trying to implement a simple ostream_itreator, which streams every N-th element, but i get a type error
error: no type named ‘value_type’ in ‘struct std::iterator_traits<outIterator<int> >’ typedef typename iterator_traits<_OI>::value_type _ValueTypeO;
Code:
#include <iostream> #include <vector> #include <iterator> template<class T> class outIterator { std::ostream *stream; size_t N; const char* delim; size_t counter = 0; public: // initialization outIterator(std::ostream& out) : stream(&out) , N(1) , delim(" ") {} outIterator(std::ostream& out, size_t N, const char* delimiter) : stream(&out) , N(N) , delim(delimiter) {} // = outIterator<T>& operator= (const T& value) { if (counter % N == 0){ *stream << value << delim; } return *this; } }; int main() { outIterator<int> out(std::cout, 2, " "); std::vector<int> vec {0, 1, 2, 3, 4, 5}; std::copy(vec.begin(), vec.end(), out); return 0; }
Also i didn’t include overloadings ++ and ++(int). They increment counter and return *this. And * overloading that returns *this
Error description:
/usr/include/c++/7/bits/stl_algobase.h:378:57: error: no type named ‘value_type’ in ‘struct std::iterator_traits<outIterator<int> >’ typedef typename iterator_traits<_OI>::value_type _ValueTypeO; ^~~~~~~~~~~ /usr/include/c++/7/bits/stl_algobase.h:383:9: error: no type named ‘value_type’ in ‘struct std::iterator_traits<outIterator<int> >’ const bool __simple = (__is_trivial(_ValueTypeI) ~~~~~~~~~~~~~~~~~~~~~~~~~~ && __is_pointer<_II>::__value ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ && __is_pointer<_OI>::__value ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ && __are_same<_ValueTypeI, _ValueTypeO>::__value); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Answer
Custom iterator types must either contain member typedefs for difference_type
, value_type
, pointer
, reference
, and iterator_category
or specialize std::iterator_traits
to provide the same.
In your specific case, you should modify your outIterator
template like this:
template <typename T> class outIterator { //... public: using difference_type = std::ptrdiff_t; using value_type = T; using pointer = T*; using reference = T&; using iterator_category = std::output_iterator_tag; //... };