0

I'm working on making a linkedlist class for some practice. I want it to support iteration, so I've given it an iterator class. However, I'm getting some compilation errors. Here is a shortened version of my code.

t.cpp

#include "t.hpp"

int main()
{
    return 0;
}

t.hpp

#ifndef LINKEDLIST_HPP
#define LINKEDLIST_HPP 1

#include <cstddef>
#include <iterator>    

template <typename T>
class LinkedList {
private:
    template <typename V> class Iterator;
    template <typename V> struct ListNode;
public:
    typedef Iterator<T> iterator;
    iterator begin();
    iterator end();
private:
    template <typename V>
    class Iterator : public std::iterator<std::forward_iterator_tag, T> {
    public:
        Iterator<T>& operator++();
    private:
        friend class LinkedList;
        Iterator() = delete;
        Iterator(ListNode<T>* node) : current_{node} { }
        ListNode<T>* current_;
    };

    template <typename V>
    struct ListNode
    {
        T value_;
        ListNode<T>* next_;
    };

    ListNode<T>* head_;
    ListNode<T>* tail_;
};

template <typename T> inline
typename LinkedList<T>::iterator LinkedList<T>::begin() 
{
    return iterator{head_}; 
}

template <typename T> inline
typename LinkedList<T>::iterator LinkedList<T>::end()
{
    return iterator{nullptr};
}

template <typename T> inline
typename LinkedList<T>::iterator& 
LinkedList<T>::iterator::operator++()
{
    current_ = current_->next_;
    return *this;
}

#endif

Now I have a sneaking suspicion that the line typedef Iterator<T> iterator either doesn't quite work like I think it should, or it is bad practice by concealing the fact that iterator is a template type. However, I don't get any obvious warnings from my compiler (mingw32-g++ 4.8.1) about that.

I'm compiling this using

$ mingw32-g++ -g -Wall -Werror -Wextra -pedantic -std=gnu++11 t.cpp

which gives me the error

t.hpp:60:33: error: specializing member 'LinkedList<T>::Iterator<T>::operator++' requires 'template<>' syntax
 typename LinkedList<T>::iterator& 
                                 ^

Okay, so I give it the template syntax there.

template <typename T> inline
typename LinkedList<T>::iterator<T>& 
LinkedList<T>::iterator::operator++() { }

Where I then get the compilation error

t.hpp:60:25: error: non-template 'iterator' used as template
 typename LinkedList<T>::iterator<T>& 
                         ^  
t.hpp:60:25: note: use 'LinkedList<T>::template iterator' to indicate that it is a template

t.hpp:60:25: error: expected unqualified-id at end of input
                ^

Okay, so I use template

template <typename T> inline
typename LinkedList<T>::template iterator<T>& 
LinkedList<T>::iterator::operator++() { }

And get this error now

t.hpp:60:45: error: specializing member 'LinkedList<T>::Iterator<T>::operator++' requires 'template<>' syntax
 typename LinkedList<T>::template iterator<T>& 
                                             ^

Which is where I get stuck. I've read these questions

which seem to indicate that I need to put a template<> somewhere. I'm just not sure I understand where it should go.

How should I attempt to do what I'm doing here?

Community
  • 1
  • 1
Dan Oberlam
  • 2,435
  • 9
  • 36
  • 54
  • 3
    I don't think you really wanted to make the iterator itself a template in the first place. – chris Mar 10 '15 at 20:53
  • 2
    Nor the node, for that matter. – T.C. Mar 10 '15 at 20:56
  • @chris I realize after your comments that there isn't a point to having either of those things be templates, and removing that fixed all of my errors. – Dan Oberlam Mar 10 '15 at 21:04
  • @T.C. If either (or both) of you wish to leave an answer to that effect I'd be happy to accept and upvote. – Dan Oberlam Mar 10 '15 at 21:05
  • I'm actually doing this for a class right now. I'm curious if you've actually iterated through a list? We had our entire `iterator` class under `public` and it seems that your default ctor isn't permitted since it's `private`. It appears to me that someone won't be able to do `LinkedList::Iterator iter;` Then later assign it to `begin()`. – TriHard8 Mar 10 '15 at 22:31
  • @TriHard8 Yeah, it works fine. If you look under the definition of `Iterator` it says `friend class LinkedList;` which gives `LinkedList` access to the constructor. I've also `typedef`'d the `Iterator` as `iterator` which is what users of the class would have access to. – Dan Oberlam Mar 10 '15 at 22:35
  • @Dannnno cool. It's always fun looking at other people's code to see how drastically different the same thing can be accomplished. – TriHard8 Mar 10 '15 at 22:39

0 Answers0