You are here:

C++/STL Iterator

Advertisement


Question
I have wrote my own Multiset Container and Iterator class.
My Iterator class have a pointer point to a Multiset element.

And then , I make my iterator be a STL iterator. So I can use the STL algorithms.

My Iterator class is shown here :

template<class Key, class Comp = less<Key>, class A = allocator<Key> >
class Multiset ;

template<class C,typename T, class D = ptrdiff_t >
class Iterator  
{
    typedef T      value_type;
    typedef D      difference_type;
   typedef C   iterator_category;
   typedef T*      pointer;
   typedef T&      reference;

   friend Multiset<T>;

public:
  Iterator(){}
  Iterator(CNode<T>* m_Node);
  pointer operator->() const;
  reference operator*() const;
  Iterator<C,T>& operator++();
  Iterator<C,T> operator++(int);
  Iterator<C,T>& operator--();
  Iterator<C,T> operator--(int);

  bool operator ==(const Iterator& rhs) const;
  bool operator !=(const Iterator& rhs) const;
protected:

  CNode<T>* mIt; // an element of Multiset
  unsigned long GetKey();
  void increment();
  void decrement();
  CNode<T>* GetNode()
};


But , when I use the upper_bound function in algorithm library of C, there is a error :

...\include\algorithm(847) : error C2784: '_D *__cdecl std::_Dist_type(const struct std::iterator<_C,_Ty,_D> &)' : could not deduce template argument for 'const struct std::iterator<_C,_Ty,_D> &' from 'class Iterator<struct std::bidirectional_iterator_tag,double,int>'

How can I solve this. My iterator class is correct ? What are the requirement for an standard iterator of C (for multiset)

Answer
It would have saved me a good few minutes (half hour maybe) if you had said straight out what compiler, version and C++ standard library implementation and version you are using. Please do this in all future questions that are compiler/library specific and also what operating system etc. if relevant (for example if you ask me about mouse clicks expecting Linux/Gnome and do not mention Linux/Gnome then I will probably assume Windows). Not all compilers and library implementations are equal. Most fall short of the C++ standard. And they do it in different areas.

Anyhow, as far as I can tell you are using a version of MSVC++ 6 or maybe 5, with the C++/STL implementation that shipped with these products. Note that this is a _very_ old and somewhat broken/limited STL implementation. It originally shipped with VC5.

Note that I had to trawl through the header files for various VC++ versions STL implementations to find this out. Not fun. Waste of my time. Maybe I have wasted so much time I cannot answer your problem. I am certainly not very well disposed towards you.

You also have not shown enough code for me to recreate the problem without even more effort and so I cannot give an answer that I know is totally correct. And no I do _not_ want you to post large quantities of code either. I expect you to par the posted example code down to the absolute minimum that is complete and shows the problem. I can then copy and paste into a test code source file and see if I can recreate the problem, and also spot any further problems. In fact in doing this you may find you fix some problems on your own <g>.

Remember that AllExperts experts answer on a volunteer basis. We have our own lives to get on with as well. The easier you make it for us to help you the more likely it is you will get help and good help.

In my VC6 installation I see that the C++ STL implementation internal inline function template _Dist_type is defined as follows in header file iterator:

template<class _C, class _Ty, class _D> inline
  _D *_Dist_type(const iterator<_C, _Ty, _D>&)
  {return ((_D *)0); }

Which matches your error message information.

You will notice that the type passed to specialisations of this function template is a reference to a class template specialisation of std::iterator (in header utility).

I suspect then the ALL iterator types for this implementation would require deriving from a std::iterator specialisation. It seems that you may have started out from this or similar code. However try something like:

template<typename T, class D = ptrdiff_t >
class Iterator  
: public std::iterator<std::bidirectional_iterator_tag, T, D>
{
// ...
};

There is no point parameterising your iterator on its category, as just saying it is a random access iterator will not make it one and a bidirectional iterator is a forward iterator which is an input iterator.

For reference compare with the latest VC++ 2005 STL version of _Dist_type:

template<class _Iter> inline
  typename iterator_traits<_Iter>::difference_type
     * __CLRCALL_OR_CDECL _Dist_type(_Iter)
  {   // return distance type from arbitrary argument
  return (0);
  }

I suspect this would have worked better with your iterator class template definition.

I have only concerned myself with the immediate problem of the error you received due to all the initial time wasted finding out what was what, so you may find your iterator implementation needs a bit more work.

For more information on writing your own iterators, and the C++ standard library in general see "The C++ Standard Library A Tutorial and Reference" by Nicolai M. Josuttis. Also get a better C++ standard library implementation (see http://www.stlport.org/, http://www.dinkumware.com/) and maybe a compiler that understands more of standard C++ than VC6 does (see for example http://msdn.microsoft.com/vstudio/express/visualC/default.aspx).  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2016 About.com. All rights reserved.