I have a class that is using a list for its implementation :
template<class T>
class Ring {
list<T> lst;
..
I want the underliyng implementation (data structure) to be chosen using the template arguments and it should defaults to list
. I thought it should be done like that:
template<class T,class Y = list<T>>
class Ring {
Y lst;
..
where T
is the generic type of the data structure and Y
the type of container. But it doesn't compile, where is the problem ?
Edited: Here is the full code. Now I see that the problem is in using the iterator and not in template.
#include <iostream>
#include <list>
#include <string>
using namespace std;
template<class T,class Y = list<T>>
class Ring{
Y lst;
public:
// Declaration necessary so the following
// 'friend' statement sees this 'iterator'
// instead of std::iterator:
class iterator;
friend class iterator;
class iterator : public std::iterator<
std::bidirectional_iterator_tag, T, ptrdiff_t> {
Y::iterator it;
Y* r;
public:
// "typename" necessary to resolve nesting:
iterator(Y& lst,
const typename Y::iterator& i)
: r(&lst), it(i) {}
bool operator==(const iterator& x) const {
return it == x.it;
}
bool operator!=(const iterator& x) const {
return !(*this == x);
}
Y::reference operator*() const {
return *it;
}
iterator& operator++() {
++it;
if (it == r->end())
it = r->begin();
return *this;
}
iterator operator++(int) {
iterator tmp = *this;
++*this;
return tmp;
}
iterator& operator--() {
if (it == r->begin())
it = r->end();
--it;
return *this;
}
iterator operator--(int) {
iterator tmp = *this;
--*this;
return tmp;
}
iterator insert(const T& x) {
return iterator(*r, r->insert(it, x));
}
iterator erase() {
return iterator(*r, r->erase(it));
}
};
void push_back(const T& x) {
lst.push_back(x);
}
iterator begin() {
return iterator(lst, lst.begin());
}
int size() { return lst.size(); }
};
int main() {
Ring<string> rs;
rs.push_back("one");
rs.push_back("two");
rs.push_back("three");
rs.push_back("four");
rs.push_back("five");
Ring<string>::iterator it = rs.begin();
it++; it++;
it.insert("six");
it = rs.begin();
// Twice around the ring:
for (int i = 0; i < rs.size() * 2; i++)
cout << *it++ << endl;
} ///:~
Errors :
Severity Code Description Project File Line Suppression State
Error C2061 syntax error: identifier 'iterator' STLCont d:\c++ projects\volume 2\stlcont\stlcont\ring.cpp 16
Error C2238 unexpected token(s) preceding ';' STLCont d:\c++ projects\volume 2\stlcont\stlcont\ring.cpp 16
Error C2061 syntax error: identifier 'reference' STLCont d:\c++ projects\volume 2\stlcont\stlcont\ring.cpp 29
Error C2079 'it' uses undefined class 'Ring<std::string,std::list<T,std::allocator<_Ty>>>::iterator' STLCont d:\c++ projects\volume 2\stlcont\stlcont\ring.cpp 77
Error C2334 unexpected token(s) preceding '{'; skipping apparent function body STLCont d:\c++ projects\volume 2\stlcont\stlcont\ring.cpp 29
Error C2027 use of undefined type 'Ring<std::string,std::list<T,std::allocator<_Ty>>>::iterator' STLCont d:\c++ projects\volume 2\stlcont\stlcont\ring.cpp 77
Error C2228 left of '.insert' must have class/struct/union STLCont d:\c++ projects\volume 2\stlcont\stlcont\ring.cpp 79
Error C2027 use of undefined type 'Ring<std::string,std::list<T,std::allocator<_Ty>>>::iterator' STLCont d:\c++ projects\volume 2\stlcont\stlcont\ring.cpp 80
Error C2100 illegal indirection STLCont d:\c++ projects\volume 2\stlcont\stlcont\ring.cpp 83
Error C2088 '<<': illegal for class STLCont d:\c++ projects\volume 2\stlcont\stlcont\ring.cpp 83