std :: list oneのようなリストのテンプレートを書こうとしています。 これはList.hで私のコードです:私のstd :: list実装のイテレータは動作しません
#include <memory>
#include <cassert>
#include <iterator>
template<typename T, class Node>
class iterator : public std::iterator<std::bidirectional_iterator_tag, Node *, Node &> {
Node *underlying;
public:
explicit iterator(Node *n) : underlying(n) { };
iterator() : underlying(nullptr) { };
iterator &operator++() { //preinc
assert(underlying != nullptr && "Out-of-bounds iterator increment!");
underlying = underlying->next;
return *this;
}
iterator operator++(int) { //postinc
assert(underlying != nullptr && "Out-of-bounds iterator increment!");
iterator temp(*this);
++(*this);
return temp;
}
iterator &operator--() { //predec
assert(underlying != nullptr && "Out-of-bounds iterator decrement!");
underlying = underlying->previous;
return *this;
}
iterator operator--(int) { //postdec
assert(underlying != nullptr && "Out-of-bounds iterator decrement!");
iterator temp(*this);
--(*this);
return temp;
}
bool operator==(const iterator &rhs) {
return underlying == rhs.underlying;
}
bool operator!=(const iterator &rhs) {
return underlying != rhs.underlying;
}
T &operator*() {
return underlying->data;
}
};
template<typename T>
class List {
class Node {
public:
T data;
Node *previous;
Node *next; //is that T needed?
Node(T &d) : data(d) { };
};
private:
Node *head; //first element
Node *tail;
void create() { head = tail = NULL; }
void create(const List &rhs) {
iterator this_iter = head;
iterator rhs_iter = rhs.head;
while (rhs_iter != NULL) {
this_iter->data = (rhs_iter++)->data;
++this_iter;
}
};
public:
typedef T *iterator;
typedef const T *const_iterator;
typedef size_t size_type;
typedef T value_type;
List() { create(); };
List &operator=(const List &rhs) {
if (&rhs != this) {
create(rhs);
}
return *this;
};
List(const List &rhs) { create(rhs); };
~List() { while(head) remove(head); };
T *begin() { return head; };
T *end() { return tail; };
T front() { return head->data; };
T back() { return tail->data; };
bool empty() { return head == NULL; }
size_type size() {
size_t i = 0;
Node *node = head;
while (node) {
node = node->next;
i++;
}
return i;
};
T &operator[](size_type i) {
if (i < size() && i >= 0) {
Node *temp = head;
while (i > 0) {
temp = temp->next;
i--;
}
return temp->data;
}
throw std::out_of_range("Index out of range");
};
// const T &operator[](size_type i) const; //how to implement and do not duplicate code?
Node *push_back(value_type data) {
Node *n = new Node(data);
if (head == NULL) {
head = tail = n;
} else {
n->previous = tail;
tail->next = n;
tail = n;
}
return n;
};
Node *push_front(value_type data) {
Node *n = new Node(data);
if (head == NULL) {
head = tail = n;
} else {
n->next = head;
head->previous = n;
head = n;
}
return n;
};
void pop_front() {
remove(head);
};
void pop_back() {
remove(tail);
};
void remove(Node *n){
if(n == NULL) return;
if(n == head){
head = n->next;
head->previous =NULL;
}
else if(n == tail){
tail = n->previous;
tail->next = NULL;
}
else{
n->previous->next = n->next;
n->next->previous = n->previous;
}
delete n;
}
};
そして、これはmain.cppに
#include <iostream>
#include "List.h"
int main(){
List<int> l;
l.push_back(1);
l.push_back(2);
l.push_back(3);
l.pop_back();
l.pop_front();
l.push_back(4);
l.push_back(5);
for (size_t i = 0; i < l.size(); i++)
std::cout << l[i] << "\n";
std::cout<<"Front "<<l.front();
std::cout<<"Back "<<l.back();
}
実は一back /フロント、pop_back /フロントと[]オペレータの作業罰金です。しかし、フロント()またはバック()を使用しようとすると「終了コード139で処理が完了しました」というメッセージが表示されます。 エラーそして、私はリストテンプレートのこのイテレータが動作しないことを知っていますが、私はそれを組み合わせる方法を知っています。誰かがヒントや助けてもらえますか?
EDIT: Ok、私はremoveとfront()、tail()メソッドの問題を修正しました。しかし、イテレータのことはまだ動作しません。 たとえば、このコード:
for(List<int>::iterator it = l.begin(); it!=l.end(); it++){
std::cout << it << "\n";
}
は私にerrosを与える:
error: cannot convert ‘List<int>::Node*’ to ‘List<int>::iterator {aka int*}’ in initialization
for(List<int>::iterator it = l.begin(); it!=l.end(); it++){
^
error: comparison between distinct pointer types ‘List<int>::iterator {aka int*}’ and ‘List<int>::Node*’ lacks a cast [-fpermissive]
for(List<int>::iterator it = l.begin(); it!=l.end(); it++){
^
私はテ問題はイテレータテンプレートでノードをwrapingであると私は「型名Tの*イテレータ」を持っていることを知っています。
あなたの 'Node(T&d)'は 'next'も' previous'も設定しません...おそらく大きな問題はありません – PiotrNycz
このコードをテストしてください!空リストを作成する - 空であるかどうかをチェックする - 関数を呼び出して、すべてが正しく動作するかどうかを確認する。 1つの要素でリストを作成する - リスト関数を呼び出す - すべてが機能することを確認する。 2つの要素Listに対して同じことを行います。その他... – PiotrNycz
あなたの問題をまだ分かっていないのであれば、誰かが助けることができるようになる前に、それを再現する最小限のプログラムを構築する必要があります。 – Useless