I have a little problem while trying to implement a container, Set, based on a linked list.
Yeah, I know that there’s an STL implementation of a set, but this is for homework. 🙂
So, this is what I have done so far:
my Set.h file looks like that:
template <class T>
class Set {
private:
typedef std::list<T> base_container;
base_container items;
public:
class myIterator {
public:
typename base_container::iterator base_iterator;
myIterator() { }
};
void addItem(const T item) {
items.push_back(item);
}
typedef typename Set<T>::myIterator setIterator;
setIterator begin() { return items.begin(); }
setIterator end() { return items.end(); }
Set<T>(void) { }
~Set<T>(void) { }
};
Now, main.cpp:
#include "Set.h"
int main(void) {
Set<int> mySet;
mySet.addItem(1);
mySet.addItem(2);
mySet.addItem(3);
mySet.addItem(4);
Set<int>::myIterator x;
x = mySet.begin(); // produces an error about non-convertible types.
return EXIT_SUCCESS;
}
The error is as follows:
error C2664: 'Set<T>::myIterator::myIterator(const Set<T>::myIterator &)' : cannot convert parameter 1 from 'std::_List_iterator<_Mylist>' to 'const Set<T>::myIterator &'
Clearly I messed things up, but I’m not sure which part of the code is actually the problem.
Any suggestions about how to fix this? Any helpful information will be appreciated.
Thanks. 🙂
There are many problems with your approach.
As others have said, you can’t create your iterator type from the underlying type:
This can be solved by adding a constructor to your type:
This constructor should be explicit, which means you need to change how you create it:
The next problem is that your type doesn’t implement the iterator interface, it doesn’t provide
operator++oroperator*etc. and it doesn’t define nested types such asvalue_typeanditeratory_categoryi.e. it’s not an iterator (just giving it a name with “iterator” in it doesn’t make it true!)Once you fix that and your type is a valid iterator, you’ll find your container can’t be used with STL-style algorithms because it doesn’t implement the container requirements. Among other things, it should provide a nested type called
iteratornotsetIteratorso that other template code can useS::iteratorwithout caring ifSis astd::set<T>or aSet<T>. Don’t call itSet<T>::setIterator, just call itSet<T>::iterator. Also in this case there’s no point definingmyIterator(noone cares that it’s yours! 🙂 then having a typedef to call itsetIterator, just name the type with the right name in the first place and you don’t need a typedef.