为遍历指针数组的 class 创建自定义迭代器
Creating an custom iterator for a class that iterates through an array of pointers
编译器说:
“未找到 Array 类型的可调用 'begin' 函数 *”
“未找到 Array 类型的可调用 'end' 函数 *”
“它未声明标识符”
在 print 函数中,我尝试使用 for(auto it: this) 遍历我的指针数组。
我按照 this 教程创建了一个自定义迭代器,但我不知道我做错了什么。
我不太确定我的迭代器结构是否定义正确,因为在他的示例中他使用了一个简单的整数数组,而我有一个指向 T 类型的指针数组。
我的问题是,我究竟应该编辑什么才能使迭代器正常工作。我想我应该从 struct Iterator 编辑一些类型,但我不太确定要编辑什么。我在底部的打印功能上使用了 auto 关键字。谢谢指教!
我的 class 的完整源代码是:
Array.h
#pragma once
#include<iostream>
using namespace std;
template<class T>
class Array
{
private:
T** List; // lista cu pointeri la obiecte de tipul T*
int Capacity; // dimensiunea listei de pointeri
int Size; // cate elemente sunt in lista
public:
struct Iterator {
using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = T;
using pointer = T *; // or also value_type*
using reference = T &; // or also value_type&
Iterator(pointer ptr) : m_ptr(ptr) {}
reference operator*() const { return *m_ptr; }
pointer operator->() { return m_ptr; }
// Prefix increment
Iterator& operator++() { m_ptr++; return *this; }
// Postfix increment
Iterator operator++(int) { Iterator tmp = *this; ++(*this); return tmp; }
friend bool operator== (const Iterator& a, const Iterator& b) { return a.m_ptr == b.m_ptr; };
friend bool operator!= (const Iterator& a, const Iterator& b) { return a.m_ptr != b.m_ptr; };
private:
pointer m_ptr;
};
Iterator begin() { return Iterator(&List[0]); }
Iterator end() { return Iterator(&List[Size-1]); }
Array(); // Lista nu e alocata, Capacity si Size = 0
~Array(); // destructor
Array(int capacity); // Lista e alocata cu 'capacity' elemente
Array(const Array<T> &otherArray); // constructor de copiere
T& operator[] (int index); // arunca exceptie daca index este out of range
const Array<T>& operator+=(T *newElem); // adauga un element de tipul T la sfarsitul listei si returneaza this
const Array<T>& Insert(int index, const T &newElem); // adauga un element pe pozitia index, retureaza this. Daca index e invalid arunca o exceptie
const Array<T>& Delete(int index); // sterge un element de pe pozitia index, returneaza this. Daca index e invalid arunca o exceptie
bool operator=(const Array<T> &otherArray);
int GetSize();
int GetCapacity();
void realocateMemory();
void printArray();
bool isIndexValid(int);
};
template<class T>
bool Array<T>::isIndexValid(int index)
{
//if (index < 0 || index > Size)
// throw Exceptions::InvalidIndex;
return true;
}
template<class T>
void Array<T>::realocateMemory()
{
T* helper = new T[Size];
for (int i = 0;i < Size;i++)
helper[i] = *List[i];
delete[] List;
Capacity *= 2;
List = new T*[Capacity];
for (int i = 0;i < Size;i++)
List[i] = new T(helper[i]);
delete[] helper;
}
template<class T>
int Array<T>::GetSize()
{
return Size;
}
template<class T>
int Array<T>::GetCapacity()
{
return Capacity;
}
template<class T>
Array<T>::Array() {
Capacity = 1;
Size = 0;
List = new T*[Capacity];
}
template<class T>
Array<T>::Array(int cap) {
Capacity = cap;
List = new T*[Capacity];
}
template<class T>
Array<T>::~Array() {
Capacity = 0;
Size = 0;
delete []List;
}
template<class T>
Array<T>::Array(const Array<T> &otherArray)
{
delete[]List;
Size = otherArray.GetSize();
Capacity = otherArray.GetCapacity();
List = new T*[Capacity];
int poz = 0;
for (auto it : otherArray)
List[poz++] = it;
}
template<class T>
T& Array<T>::operator[] (int index)
{
if (!isIndexValid(index))
throw Exceptions::InvalidIndex;
return List[index];
}
template<class T>
const Array<T>& Array<T>::operator+=(T *newElem) {
if (Size == Capacity)
realocateMemory();
List[Size++] = newElem;
return *this;
}
template<class T>
bool Array<T>::operator=(const Array<T> &otherArray)
{
delete[] List;
Capacity = otherArray.GetCapacity();
Size = otherArray.GetSize();
List = new T*[Capacity];
for (int i = 0;i < Size;i++)
List[i] = otherArray[i];
return true;
}
template<class T>
const Array<T>& Array<T>::Insert(int index, const T &newElem)
{
if (Size == Capacity)
realocateMemory();
//shift one position to right
for (int i = Size;i > index;i--)
List[i] = List[i - 1];
List[index] = new T(newElem);
Size++;
return *this;
}
template<class T>
const Array<T>& Array<T>::Delete(int index)
{
for (int i = index;i < Size - 1;i++)
List[i] = List[i + 1];
Size--;
}
template<class T>
void Array<T>::printArray()
{
for (int i = 0;i < Size;i++)
std::cout << *List[i] << ' ';
cout << "\n---------------------------------------\n";
for (auto it : this)
std::cout << *it << ' ';
cout << "\n---------------------------------------\n";
}
main.cpp
#include "Array.h"
using namespace std;
#include <vector>
int main()
{
Array<int>test;
for (int i = 0;i < 100;i++)
test += new int(i);
int x = 444;
test.Insert(0, x); //add x at index 0
test.printArray();
return 0;
}
通过更改结构中的某些类型解决。
因为是指针数组,所以需要有:
value_type 应该是 T* 因为数组中的每个元素都是
指针
指针应该是一个 T** 因为它指向一个指针数组
并且引用应该是 T*& 因为是通过 a 的引用
数组中的指针元素。
此外,在 MatG 的帮助下,for(auto it: this) 应该更改为 for(auto it: *this),因为我们需要使用这个 class 的解引用值。
如有错误请指正
#pragma once
#include<iostream>
using namespace std;
template<class T>
class Array
{
private:
T** List; // lista cu pointeri la obiecte de tipul T*
int Capacity; // dimensiunea listei de pointeri
int Size; // cate elemente sunt in lista
public:
struct Iterator {
using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = T*;
using pointer = T **; // or also value_type*
using reference = T *&; // or also value_type&
Iterator(pointer ptr) : m_ptr(ptr) {}
reference operator*() const { return *m_ptr; }
pointer operator->() { return m_ptr; }
// Prefix increment
Iterator& operator++() { m_ptr++; return *this; }
// Postfix increment
Iterator operator++(int) { Iterator tmp = *this; ++(*this); return tmp; }
friend bool operator== (const Iterator& a, const Iterator& b) { return a.m_ptr == b.m_ptr; };
friend bool operator!= (const Iterator& a, const Iterator& b) { return a.m_ptr != b.m_ptr; };
private:
pointer m_ptr;
};
Iterator begin() { return Iterator(&List[0]); }
Iterator end() { return Iterator(&List[Size]); }
Array(); // Lista nu e alocata, Capacity si Size = 0
~Array(); // destructor
Array(int capacity); // Lista e alocata cu 'capacity' elemente
Array(const Array<T> &otherArray); // constructor de copiere
T& operator[] (int index); // arunca exceptie daca index este out of range
const Array<T>& operator+=(T *newElem); // adauga un element de tipul T la sfarsitul listei si returneaza this
const Array<T>& Insert(int index, const T &newElem); // adauga un element pe pozitia index, retureaza this. Daca index e invalid arunca o exceptie
const Array<T>& Delete(int index); // sterge un element de pe pozitia index, returneaza this. Daca index e invalid arunca o exceptie
bool operator=(const Array<T> &otherArray);
int GetSize();
int GetCapacity();
void realocateMemory();
void printArray();
bool isIndexValid(int);
};
template<class T>
bool Array<T>::isIndexValid(int index)
{
//if (index < 0 || index > Size)
// throw Exceptions::InvalidIndex;
return true;
}
template<class T>
void Array<T>::realocateMemory()
{
T* helper = new T[Size];
for (int i = 0;i < Size;i++)
helper[i] = *List[i];
delete[] List;
Capacity *= 2;
List = new T*[Capacity];
for (int i = 0;i < Size;i++)
List[i] = new T(helper[i]);
delete[] helper;
}
template<class T>
int Array<T>::GetSize()
{
return Size;
}
template<class T>
int Array<T>::GetCapacity()
{
return Capacity;
}
template<class T>
Array<T>::Array() {
Capacity = 1;
Size = 0;
List = new T*[Capacity];
}
template<class T>
Array<T>::Array(int cap) {
Capacity = cap;
List = new T*[Capacity];
}
template<class T>
Array<T>::~Array() {
Capacity = 0;
Size = 0;
delete []List;
}
template<class T>
Array<T>::Array(const Array<T> &otherArray)
{
delete[]List;
Size = otherArray.GetSize();
Capacity = otherArray.GetCapacity();
List = new T*[Capacity];
int poz = 0;
for (auto it : otherArray)
List[poz++] = it;
}
template<class T>
T& Array<T>::operator[] (int index)
{
if (!isIndexValid(index))
throw Exceptions::InvalidIndex;
return List[index];
}
template<class T>
const Array<T>& Array<T>::operator+=(T *newElem) {
if (Size == Capacity)
realocateMemory();
List[Size++] = newElem;
return *this;
}
template<class T>
bool Array<T>::operator=(const Array<T> &otherArray)
{
delete[] List;
Capacity = otherArray.GetCapacity();
Size = otherArray.GetSize();
List = new T*[Capacity];
for (int i = 0;i < Size;i++)
List[i] = otherArray[i];
return true;
}
template<class T>
const Array<T>& Array<T>::Insert(int index, const T &newElem)
{
if (Size == Capacity)
realocateMemory();
//shift one position to right
for (int i = Size;i > index;i--)
List[i] = List[i - 1];
List[index] = new T(newElem);
Size++;
return *this;
}
template<class T>
const Array<T>& Array<T>::Delete(int index)
{
for (int i = index;i < Size - 1;i++)
List[i] = List[i + 1];
Size--;
}
template<class T>
void Array<T>::printArray()
{
for (int i = 0;i < Size;i++)
std::cout << *List[i] << ' ';
cout << "\n---------------------------------------\n";
for (auto it : *this)
std::cout <<*it << ' ';
cout << "\n---------------------------------------\n";
}
编译器说:
“未找到 Array
“未找到 Array
“它未声明标识符”
在 print 函数中,我尝试使用 for(auto it: this) 遍历我的指针数组。 我按照 this 教程创建了一个自定义迭代器,但我不知道我做错了什么。 我不太确定我的迭代器结构是否定义正确,因为在他的示例中他使用了一个简单的整数数组,而我有一个指向 T 类型的指针数组。 我的问题是,我究竟应该编辑什么才能使迭代器正常工作。我想我应该从 struct Iterator 编辑一些类型,但我不太确定要编辑什么。我在底部的打印功能上使用了 auto 关键字。谢谢指教!
我的 class 的完整源代码是: Array.h
#pragma once
#include<iostream>
using namespace std;
template<class T>
class Array
{
private:
T** List; // lista cu pointeri la obiecte de tipul T*
int Capacity; // dimensiunea listei de pointeri
int Size; // cate elemente sunt in lista
public:
struct Iterator {
using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = T;
using pointer = T *; // or also value_type*
using reference = T &; // or also value_type&
Iterator(pointer ptr) : m_ptr(ptr) {}
reference operator*() const { return *m_ptr; }
pointer operator->() { return m_ptr; }
// Prefix increment
Iterator& operator++() { m_ptr++; return *this; }
// Postfix increment
Iterator operator++(int) { Iterator tmp = *this; ++(*this); return tmp; }
friend bool operator== (const Iterator& a, const Iterator& b) { return a.m_ptr == b.m_ptr; };
friend bool operator!= (const Iterator& a, const Iterator& b) { return a.m_ptr != b.m_ptr; };
private:
pointer m_ptr;
};
Iterator begin() { return Iterator(&List[0]); }
Iterator end() { return Iterator(&List[Size-1]); }
Array(); // Lista nu e alocata, Capacity si Size = 0
~Array(); // destructor
Array(int capacity); // Lista e alocata cu 'capacity' elemente
Array(const Array<T> &otherArray); // constructor de copiere
T& operator[] (int index); // arunca exceptie daca index este out of range
const Array<T>& operator+=(T *newElem); // adauga un element de tipul T la sfarsitul listei si returneaza this
const Array<T>& Insert(int index, const T &newElem); // adauga un element pe pozitia index, retureaza this. Daca index e invalid arunca o exceptie
const Array<T>& Delete(int index); // sterge un element de pe pozitia index, returneaza this. Daca index e invalid arunca o exceptie
bool operator=(const Array<T> &otherArray);
int GetSize();
int GetCapacity();
void realocateMemory();
void printArray();
bool isIndexValid(int);
};
template<class T>
bool Array<T>::isIndexValid(int index)
{
//if (index < 0 || index > Size)
// throw Exceptions::InvalidIndex;
return true;
}
template<class T>
void Array<T>::realocateMemory()
{
T* helper = new T[Size];
for (int i = 0;i < Size;i++)
helper[i] = *List[i];
delete[] List;
Capacity *= 2;
List = new T*[Capacity];
for (int i = 0;i < Size;i++)
List[i] = new T(helper[i]);
delete[] helper;
}
template<class T>
int Array<T>::GetSize()
{
return Size;
}
template<class T>
int Array<T>::GetCapacity()
{
return Capacity;
}
template<class T>
Array<T>::Array() {
Capacity = 1;
Size = 0;
List = new T*[Capacity];
}
template<class T>
Array<T>::Array(int cap) {
Capacity = cap;
List = new T*[Capacity];
}
template<class T>
Array<T>::~Array() {
Capacity = 0;
Size = 0;
delete []List;
}
template<class T>
Array<T>::Array(const Array<T> &otherArray)
{
delete[]List;
Size = otherArray.GetSize();
Capacity = otherArray.GetCapacity();
List = new T*[Capacity];
int poz = 0;
for (auto it : otherArray)
List[poz++] = it;
}
template<class T>
T& Array<T>::operator[] (int index)
{
if (!isIndexValid(index))
throw Exceptions::InvalidIndex;
return List[index];
}
template<class T>
const Array<T>& Array<T>::operator+=(T *newElem) {
if (Size == Capacity)
realocateMemory();
List[Size++] = newElem;
return *this;
}
template<class T>
bool Array<T>::operator=(const Array<T> &otherArray)
{
delete[] List;
Capacity = otherArray.GetCapacity();
Size = otherArray.GetSize();
List = new T*[Capacity];
for (int i = 0;i < Size;i++)
List[i] = otherArray[i];
return true;
}
template<class T>
const Array<T>& Array<T>::Insert(int index, const T &newElem)
{
if (Size == Capacity)
realocateMemory();
//shift one position to right
for (int i = Size;i > index;i--)
List[i] = List[i - 1];
List[index] = new T(newElem);
Size++;
return *this;
}
template<class T>
const Array<T>& Array<T>::Delete(int index)
{
for (int i = index;i < Size - 1;i++)
List[i] = List[i + 1];
Size--;
}
template<class T>
void Array<T>::printArray()
{
for (int i = 0;i < Size;i++)
std::cout << *List[i] << ' ';
cout << "\n---------------------------------------\n";
for (auto it : this)
std::cout << *it << ' ';
cout << "\n---------------------------------------\n";
}
main.cpp
#include "Array.h"
using namespace std;
#include <vector>
int main()
{
Array<int>test;
for (int i = 0;i < 100;i++)
test += new int(i);
int x = 444;
test.Insert(0, x); //add x at index 0
test.printArray();
return 0;
}
通过更改结构中的某些类型解决。 因为是指针数组,所以需要有:
value_type 应该是 T* 因为数组中的每个元素都是 指针
指针应该是一个 T** 因为它指向一个指针数组
并且引用应该是 T*& 因为是通过 a 的引用 数组中的指针元素。
此外,在 MatG 的帮助下,for(auto it: this) 应该更改为 for(auto it: *this),因为我们需要使用这个 class 的解引用值。 如有错误请指正
#pragma once
#include<iostream>
using namespace std;
template<class T>
class Array
{
private:
T** List; // lista cu pointeri la obiecte de tipul T*
int Capacity; // dimensiunea listei de pointeri
int Size; // cate elemente sunt in lista
public:
struct Iterator {
using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = T*;
using pointer = T **; // or also value_type*
using reference = T *&; // or also value_type&
Iterator(pointer ptr) : m_ptr(ptr) {}
reference operator*() const { return *m_ptr; }
pointer operator->() { return m_ptr; }
// Prefix increment
Iterator& operator++() { m_ptr++; return *this; }
// Postfix increment
Iterator operator++(int) { Iterator tmp = *this; ++(*this); return tmp; }
friend bool operator== (const Iterator& a, const Iterator& b) { return a.m_ptr == b.m_ptr; };
friend bool operator!= (const Iterator& a, const Iterator& b) { return a.m_ptr != b.m_ptr; };
private:
pointer m_ptr;
};
Iterator begin() { return Iterator(&List[0]); }
Iterator end() { return Iterator(&List[Size]); }
Array(); // Lista nu e alocata, Capacity si Size = 0
~Array(); // destructor
Array(int capacity); // Lista e alocata cu 'capacity' elemente
Array(const Array<T> &otherArray); // constructor de copiere
T& operator[] (int index); // arunca exceptie daca index este out of range
const Array<T>& operator+=(T *newElem); // adauga un element de tipul T la sfarsitul listei si returneaza this
const Array<T>& Insert(int index, const T &newElem); // adauga un element pe pozitia index, retureaza this. Daca index e invalid arunca o exceptie
const Array<T>& Delete(int index); // sterge un element de pe pozitia index, returneaza this. Daca index e invalid arunca o exceptie
bool operator=(const Array<T> &otherArray);
int GetSize();
int GetCapacity();
void realocateMemory();
void printArray();
bool isIndexValid(int);
};
template<class T>
bool Array<T>::isIndexValid(int index)
{
//if (index < 0 || index > Size)
// throw Exceptions::InvalidIndex;
return true;
}
template<class T>
void Array<T>::realocateMemory()
{
T* helper = new T[Size];
for (int i = 0;i < Size;i++)
helper[i] = *List[i];
delete[] List;
Capacity *= 2;
List = new T*[Capacity];
for (int i = 0;i < Size;i++)
List[i] = new T(helper[i]);
delete[] helper;
}
template<class T>
int Array<T>::GetSize()
{
return Size;
}
template<class T>
int Array<T>::GetCapacity()
{
return Capacity;
}
template<class T>
Array<T>::Array() {
Capacity = 1;
Size = 0;
List = new T*[Capacity];
}
template<class T>
Array<T>::Array(int cap) {
Capacity = cap;
List = new T*[Capacity];
}
template<class T>
Array<T>::~Array() {
Capacity = 0;
Size = 0;
delete []List;
}
template<class T>
Array<T>::Array(const Array<T> &otherArray)
{
delete[]List;
Size = otherArray.GetSize();
Capacity = otherArray.GetCapacity();
List = new T*[Capacity];
int poz = 0;
for (auto it : otherArray)
List[poz++] = it;
}
template<class T>
T& Array<T>::operator[] (int index)
{
if (!isIndexValid(index))
throw Exceptions::InvalidIndex;
return List[index];
}
template<class T>
const Array<T>& Array<T>::operator+=(T *newElem) {
if (Size == Capacity)
realocateMemory();
List[Size++] = newElem;
return *this;
}
template<class T>
bool Array<T>::operator=(const Array<T> &otherArray)
{
delete[] List;
Capacity = otherArray.GetCapacity();
Size = otherArray.GetSize();
List = new T*[Capacity];
for (int i = 0;i < Size;i++)
List[i] = otherArray[i];
return true;
}
template<class T>
const Array<T>& Array<T>::Insert(int index, const T &newElem)
{
if (Size == Capacity)
realocateMemory();
//shift one position to right
for (int i = Size;i > index;i--)
List[i] = List[i - 1];
List[index] = new T(newElem);
Size++;
return *this;
}
template<class T>
const Array<T>& Array<T>::Delete(int index)
{
for (int i = index;i < Size - 1;i++)
List[i] = List[i + 1];
Size--;
}
template<class T>
void Array<T>::printArray()
{
for (int i = 0;i < Size;i++)
std::cout << *List[i] << ' ';
cout << "\n---------------------------------------\n";
for (auto it : *this)
std::cout <<*it << ' ';
cout << "\n---------------------------------------\n";
}