前提・実現したいこと
課題で提示されたコードを元に、vectorとlist用の簡易イテレータを自作しているのですが、コンパイルしようとすると大量のエラーメッセージがでてしまいます。よく調べてみると、どうやらiteratorクラスがvector, listのメンバーではない故にエラーが起こっているようですが、ちゃんと親クラス?内にiteratorクラスを作っているのでなんでこうなるのかわかりません…どう解決すればいいのでしょうか…
このエラーばかり出てコンパイルできないので、肝心のiterator内の関数の挙動が確認できず、正しくかけているのかわかりません。もしよろしければ、iteratorクラスが正しく書けているかチェックして、間違えている所などあれば指摘や助言などしてくださるとありがたいです。
main.cppを改変することは許可されていないので、
mainをいじらない解決方法を教えてくださると助かります。
発生している問題・エラーメッセージ
E0135 class "Vector<int>" has no member "Iterator"などなど百件以上…
該当のソースコード
C++
1template<typename T> 2class Vector 3{ 4 T* mData; 5 int mSize; 6 int mCapacity; 7 8 static T sUndefined; 9public: 10 11 12 Vector()// O(1) 13 { 14 mSize = 0; 15 mCapacity = 15; 16 mData = new T[mCapacity]; 17 } 18 Vector(const Vector<T>& tOther) : Vector(); // O(n) 19 20 Vector& operator =(const Vector<T>& tRHS); // O(n) 21 22 ~Vector(); 23 24 void PushBack(const T& tItem); // O(1) 25 26 void PopBack();// O(1) 27 28 void PushFront(const T& tItem);// O(n) 29 30 void PopFront(); // O(n) 31 32 T& At(int tWhere) const; // O(1) 33 34 void Clear(); // O(1) 35 36 int Size() const; // O(1) 37 38 void Reserve(int tCount); // O(n) 39 40 int Capacity() const; // O(1) 41 42 43 class Iterator 44 { 45 int mCurrentIndex = 0; 46 Vector<T> *mMyVector = nullptr; 47 friend class Vector<T>; 48 49 Iterator(Vector<T> *tWho, int tLocation) 50 { 51 mMyVector = tWho; 52 mCurrentIndex = tLocation; 53 } 54 public: 55 T& GetData() 56 { 57 if (mMyVector[mCurrentIndex] != nullptr) 58 { 59 return mMyVector[mCurrentIndex]; 60 } 61 return sUndefined; 62 } 63 void Next() 64 { 65 mCurrentIndex += 1; 66 } 67 bool IsEqual(const Iterator& rhs) 68 { 69 int tCount = 0; 70 mCurrentIndex = 0; 71 int tSize = mMyVector->Size(); 72 73 while (tSize != mCurrentIndex-1) 74 { 75 if (mMyVector[mCurrentIndex] == rhs.GetData) 76 { 77 tCount++; 78 } 79 mCurrentIndex++; 80 } 81 82 if (tCount == tSize) 83 { 84 return true; 85 } 86 else 87 { 88 return false; 89 } 90 } 91 }; 92 93 Iterator Insert(Iterator tWhere, const T& tWhat) 94 { 95 if (mSize == mCapacity) 96 Reserve(2 * mCapacity); 97 98 int tSize = 0; 99 int tRet = 0; 100 T* tData = new T[mCapacity]; 101 102 for (int i = 0; i < mSize; i++) 103 { 104 if(mData[i] == tWhere) 105 { 106 tData[tSize] = tWhat; 107 tSize++; 108 tRet = i + 1; 109 } 110 tData[tSize] = mData[i]; 111 ++tSize; 112 } 113 114 delete[] mData; 115 mData = tData; 116 mSize = tSize; 117 118 Iterator tAnswer(mData, tRet); 119 return tAnswer; 120 } 121 Iterator Erase(Iterator tWhere) 122 { 123 int tSize = 0; 124 int tRet = 0; 125 T* tData = new T[mCapacity]; 126 127 for (int i = 0; i < mSize; i++) 128 { 129 if (mData[i] == tWhere) 130 { 131 ++tSize; 132 tData[i] = mData[tSize]; 133 tRet = i+1; 134 } 135 tData[i] = mData[tSize]; 136 ++tSize; 137 } 138 139 delete[] mData; 140 mData = tData; 141 mSize = i; 142 143 Iterator tAnswer(mData, tRet); 144 return tAnswer; 145 } 146 Iterator Begin() 147 { 148 Iterator tAnswer(mData, 0); 149 return tAnswer; 150 } 151 Iterator End() 152 { 153 Iterator tAnswer(mData, mSize); 154 return tAnswer; 155 } 156}; 157 158template<typename T> 159T Vector<T>::sUndefined;
C++
1template <typename T> 2class List 3{ 4 struct ListNode 5 { 6 ListNode() 7 { 8 mPrev = nullptr; 9 mNext = nullptr; 10 } 11 T mData; 12 ListNode* mPrev; 13 ListNode* mNext; 14 }; 15 16 ListNode* mHead; 17 ListNode* mTail; 18 19public: 20 List() 21 { 22 //mHead = nullptr;// Technically works, but we gain so much with sentinel nodes 23 //mTail = nullptr; 24 25 mHead = new ListNode;// You always know there is a node to the left and right 26 mTail = new ListNode; 27 mHead->mNext = mTail; 28 mTail->mPrev = mHead; 29 } 30 List(const List& tOther) : List(); 31 32 List& operator = (const List& tRHS); 33 34 ~List(); 35 36 void PushFront(const T& tWhat); 37 38 void PopFront(); 39 40 static T sUnspecifiedStaticVar; 41 42 T& Front(); 43 44 void PushBack(const T& tWhat); 45 46 void PopBack(); 47 48 T& Back(); 49 50 int Size(); 51 52 void Clear(); 53 54 T& At(int tWhere) const; 55 56 class Iterator 57 { 58 ListNode* mCurrent; 59 friend class List<T>; 60 Iterator(ListNode* tStart) 61 { 62 mCurrent = tStart; 63 } 64 public: 65 T& GetData() 66 { 67 return mCurrent->mData; 68 } 69 void Next() 70 { 71 mCurrent = mCurrent->mNext; 72 } 73 bool IsEqual(const Iterator& rhs) const 74 { 75 return mCurrent == rhs.mCurrent; 76 } 77 }; 78 79 Iterator Insert(Iterator tWhere, const T& tWhat) 80 { 81 ListNode* tNew = new ListNode; 82 tNew->mData = tWhat; 83 84 ListNode* tPrev = tWhere; 85 ListNode* tNext = tPrev->mNext; 86 tNext->mPrev = tPrev; 87 88 tPrev->mNext = tNew; 89 tNew->mPrev = tPrev; 90 tNew->mNext = tNext; 91 tNext->mPrev = tNew; 92 93 return Iterator(tNew->mNext); 94 } 95 Iterator Erase(Iterator tWhat) 96 { 97 ListNode* tDead = tWhat; 98 ListNode* tNext = tDead->mNext; 99 ListNode* tPrev = tDead->mPrev; 100 tPre->mNext = tDead; 101 tNext->mPrev = tDead; 102 delete tDead; 103 104 tPrev->mNext = tNext; 105 tNext->mPrev = tPrev; 106 107 return Iterator(tNext); 108 109 } 110 Iterator Begin() 111 { 112 return Iterator(mHead->mNext); 113 } 114 Iterator End() 115 { 116 return Iterator(mTail); 117 } 118};
VectorとListの関数を簡略しているので、このままコンパイルはできません。
こんな感じのmainで動かせればいいなと思います。
C++
1#include <iostream> 2#include "List.h" 3#include "Vector.h" 4 5using namespace std; 6 7int main() 8{ 9 Vector<int> tTester; 10 tTester.PushBack(0); 11 tTester.PushBack(1); 12 tTester.PushBack(2); 13 14 for (Vector<int>::Iterator iter = tTester.Begin(); !iter.IsEqual(tTester.End()); iter.Next()) 15 { 16 cout << iter.GetData() << " "; 17 } 18 19 cout << endl; 20 tTester.Erase(tTester.Begin()); 21 22 for (Vector<int>::Iterator iter = tTester.Begin(); !iter.IsEqual(tTester.End()); iter.Next()) 23 { 24 cout << iter.GetData() << " "; 25 } 26 27 cout << endl; 28 tTester.Insert(tTester.Begin(), 999); 29 tTester.Insert(tTester.Begin(), 888); 30 31 for (Vector<int>::Iterator iter = tTester.Begin(); !iter.IsEqual(tTester.End()); iter.Next()) 32 { 33 cout << iter.GetData() << " "; 34 } 35}
補足情報(FW/ツールのバージョンなど)
Visual Studio 2019 ver.16.0.2.
呼び出し側がないと超面倒ですので、呼び出し側も提示した方が回答が付きやすいですよ。
試しに、Vector<int> vec;を定義してみましたが、コンストラクタが適切に定義されていないため、エラーになります。Iteratorにまでたどり着かないです。まずは、Vectorをきちんと定義しましょう。
返答ありがとうございます。
お手数をおかけして申し訳ありません。あくまで雰囲気だけですが、呼び出し側も追加いたしました。
具体的に、Vectorのコンストラクタをどう定義をすればIteratorにたどり着くのでしょうか…?
それはまた別途質問された方が良いと思います。ただ内容的にC++の基本文法の話ですので「まるなげ」との低評価が付く可能性があります。ですので、まずはご自身でコンストラクタの書き方を調査されたほうが無用なストレスを回避できる可能性が高いです。
http://kaitei.net/cpp/constructors/