difference_type not found
Asked Answered
T

2

15

When I try to use std::distance with a custom iterator under gcc 4.7, it complains about not finding the difference_type. I have sadly no idea why it fails.

#include <iterator>

class nit {
public:
    typedef int difference_type;
};

int main() {
  const nit test1;
  std::distance( test1, test1 );
  return 0;
}

gives the error:

/usr/include/c++/4.7/bits/stl_iterator_base_funcs.h:114:5: error: no type named ‘difference_type’ in ‘struct std::iterator_traits<nit>’

Tavy answered 12/11, 2012 at 14:22 Comment(4)
Here might be the solution: cplusplus.com/forum/general/11428.Naiad
Try inheriting your class from an instance of std::iterator. I can imagine that std::iterator_traits is only specialized for things that inherit from that.Salade
Further to that, I can get further with class nit : public std::iterator<std::random_access_iterator_tag, T, int>, but T needs to be a non-void type, and you need to provide an operator- for this to work. Alternatively you can have a bidirectional_iterator_tag, but then you need to provide incrementors and comparators.Salade
That or the boost iterator library which is great for creating your own iterators.Snappy
A
8

Have you tried defining all the required types/operators?

#include <iterator>

struct nit
{
  typedef std::random_access_iterator_tag iterator_category;
  typedef int value_type;
  typedef int difference_type;
  typedef int* pointer;
  typedef int& reference;

  bool operator==(nit const&)
  {
    return true;
  }

  bool operator!=(nit const&)
  {
    return false;
  }

  int operator-(nit const&)
  {
    return 0;
  }

  nit()
  {
  }
};

int main()
{
  nit const test1;
  std::distance(test1, test1);

  return 0;
}
Ayakoayala answered 12/11, 2012 at 14:59 Comment(0)
E
1

Either, you have to provide all typedefs (with or without the help of std::iterator) in your class that std::iterator_traits is expecting or you have to specialize std::iterator_traits yourself.

This version of GCC emits other error messages but it doesn't change the fact that your code is illegal.

prog.cpp: In function ‘int main()’:
prog.cpp:9: error: uninitialized const ‘test1’
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++v4/bits/stl_iterator_base_types.h: At global scope:
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_iterator_base_types.h: In instantiation of ‘std::iterator_traits<nit>’:
prog.cpp:10:   instantiated from here
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_iterator_base_types.h:133: error: no type named ‘iterator_category’ in ‘class nit’
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_iterator_base_types.h:134: error: no type named ‘value_type’ in ‘class nit’
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_iterator_base_types.h:136: error: no type named ‘pointer’ in ‘class nit’
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_iterator_base_types.h:137: error: no type named ‘reference’ in ‘class nit’
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_iterator_base_funcs.h: In function ‘typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator) [with _InputIterator = nit]’:
prog.cpp:10:   instantiated from here
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_iterator_base_funcs.h:119: error: no matching function for call to ‘__iterator_category(nit&)’
Educated answered 12/11, 2012 at 14:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.