我尝试用迭代器创建一个类List:
#ifndef UTIL_H
#define UTIL_H
#include <iostream>
#include <exception>
namespace Util
{
class IndexOutOfBounds : public std::exception
{
virtual const char* what()
{
return "Index out of bounds";
}
};
template<class T>
class Iterator;
template <class T>
class ListNode
{
template<class R>
friend class Iterator;
template<class R>
friend class List;
public:
ListNode()
{
init();
}
ListNode(T info)
{
init();
this->info=info;
}
static void link(ListNode<T> first, ListNode<T> second)
{
first.next=&second;
second.prev=&first;
}
template<class R>
friend std::ostream& operator<< (std::ostream& out, const ListNode<R>& node);
template<class R>
friend std::istream& operator>> (std::istream& in, const ListNode<R>& node);
private:
T info;
ListNode<T>* next;
ListNode<T>* prev;
void init()
{
next=prev=this;
}
};
template<class T>
std::ostream& operator<< (std::ostream& out , const ListNode<T>& node)
{
out << node.info;
return out;
}
template<class T>
std::istream& operator>> (std::istream& in , const ListNode<T>& node)
{
in >> node.info;
return in;
}
template <class T>
class List
{
friend class ListNode<T>;
template <class R>
friend class Iterator;
private:
unsigned int length;
ListNode<T>* node;
public:
List()
{
node=new ListNode<T>();
length=0;
}
unsigned int size() const
{
return length;
}
void insert(int i,T info) throw()
{
ListNode<T>* ptr=node,*next_ptr;
try
{
if(i>(int)length || i<0)
throw IndexOutOfBounds();
for(int j=0;j<i;j++)
ptr=ptr->next;
next_ptr=ptr->next;
ptr->next=new ListNode<T>(info);
ptr->next->prev=ptr;
ListNode<T>::link(*(ptr->next),*next_ptr);
length++;
}
catch(IndexOutOfBounds& e)
{
throw e;
}
}
void push_back(T info) throw()
{
try
{
insert(length,info);
}
catch(IndexOutOfBounds& e)
{
throw e;
}
}
void push_front(T info) throw()
{
try
{
insert(0,info);
}
catch(IndexOutOfBounds& e)
{
throw e;
}
}
void remove(int i) throw()
{
ListNode<T>* ptr=node,*next_ptr;
try
{
if(i>=length || i<0)
throw IndexOutOfBounds();
for(int j=0;j<i;j++)
ptr=ptr->next;
next_ptr=ptr->next->next;
delete ptr->next;
ListNode<T>::link(*ptr,*next_ptr);
length--;
}
catch(IndexOutOfBounds& e)
{
throw e;
}
}
void pop_back() throw()
{
try
{
remove(length-1);
}
catch(IndexOutOfBounds& e)
{
throw e;
}
}
void pop_front() throw()
{
try
{
remove(0);
}
catch(IndexOutOfBounds& e)
{
throw e;
}
}
Iterator<T> begin()
{
Iterator<T> result;
result.ptr=node->next;
return result;
}
Iterator<T> last()
{
Iterator<T> result;
result.ptr=node->prev;
return result;
}
Iterator<T> end()
{
Iterator<T> result;
result.ptr=node;
return result;
}
template <class R>
friend std::ostream& operator<< (std::ostream& out , const List<R>& l);
template <class R>
friend std::istream& operator>> (std::istream& in , const List<R>& l);
typedef Iterator<T> iterator;
};
template<class T>
std::ostream& operator<< (std::ostream& out , const List<T>& l)
{
Iterator<T> i=l.begin();
return out;
}
template<class T>
std::istream& operator>> (std::istream& in , const List<T>& l)
{
for(Iterator<T> i=l.begin();i!=l.end();i++)
in >> *i;
return in;
}
template <class T>
class Iterator
{
friend class List<T>;
friend class ListNode<T>;
private:
ListNode<T>* ptr;
public:
Iterator()
{
ptr=NULL;
}
Iterator(const Iterator<T>& i)
{
ptr=i.ptr;
}
Iterator<T>& operator= (Iterator<T> i)
{
ptr=i.ptr;
return *this;
}
Iterator<T>& operator++ ()
{
ptr=ptr->next;
return *this;
}
Iterator<T> operator++ (int)
{
Iterator<T> i=*this;
++*this;
return i;
}
Iterator<T>& operator-- ()
{
ptr=ptr->prev;
return *this;
}
Iterator<T> operator-- (int)
{
Iterator<T> i=*this;
--*this;
return i;
}
T& operator* ()
{
return ptr->info;
}
template<class R>
friend bool operator!= (Iterator<R>& i, Iterator<R>& j);
template<class R>
friend bool operator== (Iterator<R>& i, Iterator<R>& j);
};
template <class T>
bool operator!= (Iterator<T>& i, Iterator<T>& j)
{
return i.ptr!=j.ptr;
}
template <class T>
bool operator== (Iterator<T>& i, Iterator<T>& j)
{
return i.ptr==j.ptr;
}
}
#endif
但是我得到了这些错误:
/home/ramy/Documents/C++/Prova/Util.h||In function ‘std::ostream& Util::operator<<(std::ostream&, const Util::List<T>&) [with T = int]’:|
/home/ramy/Documents/C++/Prova/main.cpp|11|instantiated from here|
/home/ramy/Documents/C++/Prova/Util.h|218|error: passing ‘const Util::List<int>’ as ‘this’ argument of ‘Util::Iterator<T> Util::List<T>::begin() [with T = int]’ discards qualifiers|
||=== Build finished: 1 errors, 0 warnings ===|
有了这个主要内容:
#include <iostream>
#include "Util.h"
using namespace Util;
int main(int argc, char** argv)
{
List<int> l;
for(int i=0;i<10;i++)
l.push_back(i);
std::cout << l;
return 0;
}
我不知道为什么我得到这个错误,似乎operator =被认为是对的。 这对我来说听起来很荒谬,但当然会有一个解释。
答案 0 :(得分:1)
你需要一个
ConstIterator<T> List<T>::begin() const;
// ^^^^^
使用相应的ConstIterator
类型,以便Util::operator<<
中的列表可以实际迭代该列表。非const
成员函数不能用于const
引用,即使引用本身不是const
。
当你在这里时,你应该为const
List<T>
成员函数
答案 1 :(得分:0)
看起来你在const对象上调用非const方法(begin())。