質問編集履歴

2 コードの改善

do_Shiro_to

do_Shiro_to score 15

2020/03/09 07:17  投稿

自作STLクラスのイテレータが正しく動作しません
### 前提・実現したいこと
課題で提示されたコードを元に、vectorとlist用の簡易イテレータを自作しているのですが、コンパイルしようとすると大量のエラーメッセージがでてしまいます。よく調べてみると、どうやらiteratorクラスがvector, listのメンバーではない故にエラーが起こっているようですが、ちゃんと親クラス?内にiteratorクラスを作っているのでなんでこうなるのかわかりません…どう解決すればいいのでしょうか…
このエラーばかり出てコンパイルできないので、肝心のiterator内の関数の挙動が確認できず、正しくかけているのかわかりません。もしよろしければ、iteratorクラスが正しく書けているかチェックして、間違えている所などあれば指摘や助言などしてくださるとありがたいです。
main.cppを改変することは許可されていないので、
mainをいじらない解決方法を教えてくださると助かります。
### 発生している問題・エラーメッセージ
```
E0135 class "Vector<int>" has no member "Iterator"などなど百件以上…
```
### 該当のソースコード
```C++
template<typename T>
class Vector
{
   T* mData;
   int mSize;
   int mCapacity;
   static T sUndefined;
public:
   
   Vector()// O(1)
   {
       mSize = 0;
       mCapacity = 15;
       mData = new T[mCapacity];
   }
   Vector(const Vector<T>& tOther) : Vector(); // O(n)
   Vector& operator =(const Vector<T>& tRHS); // O(n)
   
   ~Vector();
   void PushBack(const T& tItem); // O(1)
   void PopBack();// O(1)
   void PushFront(const T& tItem);// O(n)
   void PopFront(); // O(n)
   
   T& At(int tWhere) const; // O(1)
   
   void Clear(); // O(1)
   
   int Size() const; // O(1)
   
   void Reserve(int tCount); // O(n)
   
   int Capacity() const; // O(1)
   
   class Iterator
   {
       int mCurrentIndex = 0;
       Vector<T> *mMyVector = nullptr;
       Vector<T> *mMyVector = nullptr;      
       friend class Vector<T>;
       Iterator(Vector<T> *tWho, int tLocation)
       {
           mMyVector = tWho;
           mCurrentIndex = tLocation;
       }
   public:
 
       T& GetData()
       {
           if (mData[mCurrentIndex] != nullptr)
           {
               return mData[mCurrentIndex];
           if (mMyVector[mCurrentIndex] != nullptr)
           {
               return mMyVector[mCurrentIndex];
           }
           return sUndefined;
       }
       void Next()
       {
           mCurrentIndex = mCurrentIndex + 1;
           mCurrentIndex += 1;
       }
       bool IsEqual(const Iterator& rhs)
       {
           int tCount = 0;
           mCurrentIndex = 0;
           int tSize = mMyVector->Size();  
           
           while (Size() != mCurrentIndex-1)
           {
               if (mData[mCurrentIndex] == rhs.GetData)
           while (tSize != mCurrentIndex-1)
           {
               if (mMyVector[mCurrentIndex] == rhs.GetData)
               {
                   tCount++;
               }
               mCurrentIndex++;
           }
           
           
           if (tCount == Size())
           if (tCount == tSize)
           {
               return true;
           }
           else
           {
               return false;
           }
       }
       }  
   };
   Iterator Insert(Iterator tWhere, const T& tWhat) // These two use iterators now
   Iterator Insert(Iterator tWhere, const T& tWhat)
   {
       if (mSize == mCapacity)
           Reserve(2 * mCapacity);
       
       int tSize = 0;
       int tRet = 0;  
       T* tData = new T[mCapacity];
       for (int i = 0; i < mSize; i++)
       {
           if(i == tWhere)
           if(mData[i] == tWhere)
           {
               tData[tSize] = tWhat;
               tSize++;
               tRet = i + 1;         
           }
           tData[tSize] = mData[i];
           ++tSize;
       }
       
       delete[] mData;
       mData = tData;
       mSize = tSize;
       
       Iterator tAnswer(mMyVector, tWhere);
       Iterator tAnswer(mData, tRet);
       return tAnswer;
   }
   Iterator Erase(Iterator tWhere)
   {
       int tSize = 0;
       int tRet = 0;  
       T* tData = new T[mCapacity];
       for (int i = 0; i < mSize; i++)
       {
           if (i == tWhere)
           if (mData[i] == tWhere)
           {
               ++tSize;
               tData[i] = mData[tSize];
               tRet = i+1;     
           }
           tData[i] = mData[tSize];
           ++tSize;
       }
 
       delete[] mData;
       mData = tData;
       mSize = i;
       Iterator tAnswer(mMyVector, tWhere+1);
       Iterator tAnswer(mData, tRet);
       return tAnswer;
   }
   Iterator Begin()
   {
       Iterator tAnswer(mMyVector, 0);
       Iterator tAnswer(mData, 0);
       return tAnswer;
   }
   Iterator End()
   {
       Iterator tAnswer(mMyVector, mSize-1);
       Iterator tAnswer(mData, mSize);
       return tAnswer;
   }
};
template<typename T>
T Vector<T>::sUndefined;
```
```C++
template <typename T>
class List
{
   struct ListNode
   {
       ListNode()
       {
           mPrev = nullptr;
           mNext = nullptr;
       }
       T mData;
       ListNode* mPrev;
       ListNode* mNext;
   };
   ListNode* mHead;
   ListNode* mTail;
public:
   List()
   {
       //mHead = nullptr;// Technically works, but we gain so much with sentinel nodes
       //mTail = nullptr;
       mHead = new ListNode;// You always know there is a node to the left and right
       mTail = new ListNode;
       mHead->mNext = mTail;
       mTail->mPrev = mHead;
   }
   List(const List& tOther) : List();
   
   List& operator = (const List& tRHS);
   ~List();
   void PushFront(const T& tWhat);
   
   void PopFront();
   
   static T sUnspecifiedStaticVar;
   T& Front();
   void PushBack(const T& tWhat);
   void PopBack();
   T& Back();
   int Size();
   void Clear();
   T& At(int tWhere) const;
   class Iterator
   {
       ListNode* mCurrent;
       friend class List<T>;
       Iterator(ListNode* tStart)
       {
           mCurrent = tStart;
       }
   public:
       T& GetData()
       {
           return mCurrent->mData;
       }
       void Next()
       {
           mCurrent = mCurrent->mNext;
       }
       bool IsEqual(const Iterator& rhs) const
       {
           return mCurrent == rhs.mCurrent;
       }
   };
   Iterator Insert(Iterator tWhere, const T& tWhat)
   {
       ListNode* tNew = new ListNode;
       ListNode* tPrev = tWhere->mPrev;  
       ListNode* tNext = tWhere->mNext;  
       tNew->mData = tWhat;
         
       ListNode* tPrev = tWhere;  
       ListNode* tNext = tPrev->mNext;  
       tNext->mPrev = tPrev;  
       tPrev->mNext = tNew;
       tNew->mPrev = tPrev;
       tNew->mNext = tNext;
       tNext->mPrev = tNew;
       return Iterator(tNew);
       return Iterator(tNew->mNext);
   }
   Iterator Erase(Iterator tWhat)
   {
       ListNode* tPrev = tWhat->mPrev;
       ListNode* tNext = tWhat->mNext;
       delete tWhat;
       ListNode* tDead = tWhat;
       ListNode* tNext = tDead->mNext;
       ListNode* tPrev = tDead->mPrev;
       tPre->mNext = tDead;
       tNext->mPrev = tDead;
       delete tDead;
       tPrev->mNext = tNext;
       tNext->mPrev = tPrev;
       return Iterator(tNext);
   }
   Iterator Begin()
   {
       return Iterator(mHead->mNext);
   }
   Iterator End()
   {
       return Iterator(mTail);
   }
};
```
VectorとListの関数を簡略しているので、このままコンパイルはできません。  
こんな感じのmainで動かせればいいなと思います。  
```C++  
#include <iostream>  
#include "List.h"  
#include "Vector.h"  
 
using namespace std;  
 
int main()  
{  
   Vector<int> tTester;  
   tTester.PushBack(0);  
   tTester.PushBack(1);  
   tTester.PushBack(2);  
     
   for (Vector<int>::Iterator iter = tTester.Begin(); !iter.IsEqual(tTester.End()); iter.Next())  
   {  
       cout << iter.GetData() << " ";  
   }  
     
   cout << endl;  
   tTester.Erase(tTester.Begin());  
     
   for (Vector<int>::Iterator iter = tTester.Begin(); !iter.IsEqual(tTester.End()); iter.Next())  
   {  
       cout << iter.GetData() << " ";  
   }  
     
   cout << endl;  
   tTester.Insert(tTester.Begin(), 999);  
   tTester.Insert(tTester.Begin(), 888);  
     
   for (Vector<int>::Iterator iter = tTester.Begin(); !iter.IsEqual(tTester.End()); iter.Next())  
   {  
       cout << iter.GetData() << " ";  
   }  
}  
```  
 
 
### 補足情報(FW/ツールのバージョンなど)
Visual Studio 2019 ver.16.0.2.
  • C++

    8570 questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

1 脱字の修正

do_Shiro_to

do_Shiro_to score 15

2020/03/08 14:59  投稿

自作STLクラスのイテレータが正しく動作しません
### 前提・実現したいこと
課題で提示されたコードを元に、vectorとlist用の簡易イテレータを自作しているのですが、コンパイルしようとすると大量のエラーメッセージがでてしまいます。よく調べてみると、どうやらiteratorクラスがvector, listのメンバーではない故にエラーが起こっているようですが、ちゃんと親クラス?内にiteratorクラスを作っているのでなんでこうなるのかわかりません…どう解決すればいいのでしょうか…
このエラーばかり出てコンパイルできないので、肝心のiterator内の関数の挙動が確認できず、正しくかけているのかわかりません。もしよろしければ、iteratorクラスが正しく書けているかチェックして、間違えている所などあれば指摘や助言などしてくださるとありがたいです。
main.cppを改変することは許可されていないので、
mainをいじらない解決方法を教えてくださると助かります。
### 発生している問題・エラーメッセージ
```
E0135 class "Vector<int>" has no member "Iterator"などなど百件以上…
```
### 該当のソースコード
```C++
template<typename T>
class Vector
{
   T* mData;
   int mSize;
   int mCapacity;
   static T sUndefined;
public:
   
   Vector()// O(1)
   {
       mSize = 0;
       mCapacity = 15;
       mData = new T[mCapacity];
   }
   Vector(const Vector<T>& tOther) : Vector(); // O(n)
   Vector& operator =(const Vector<T>& tRHS); // O(n)
   
   ~Vector();
   void PushBack(const T& tItem); // O(1)
   void PopBack();// O(1)
   void PushFront(const T& tItem);// O(n)
   void PopFront(); // O(n)
   
   T& At(int tWhere) const; // O(1)
   
   void Clear(); // O(1)
   
   int Size() const; // O(1)
   
   void Reserve(int tCount); // O(n)
   
   int Capacity() const; // O(1)
   
   class Iterator
   {
       int mCurrentIndex = 0;
       Vector<T> *mMyVector = nullptr;
       friend class Vector<T>;
       Iterator(Vector<T> *tWho, int tLocation)
       {
           mMyVector = tWho;
           mCurrentIndex = tLocation;
       }
   public:
       T& GetData()
       {
           if (mData[mCurrentIndex] != nullptr)
           {
               return mData[mCurrentIndex];
           }
           return sUndefined;
       }
       void Next()
       {
           mCurrentIndex = mCurrentIndex + 1;
       }
       bool IsEqual(const Iterator& rhs)
       {
           int tCount = 0;
           mCurrentIndex = 0;
           
           while (Size() != mCurrentIndex-1)
           {
               if (mData[mCurrentIndex] == rhs.GetData)
               {
                   tCount++;
               }
               mCurrentIndex++;
           }
           
           
           if (tCount == Size())
           {
               return true;
           }
           else
           {
               return false;
           }
       }
       }
   };
   Iterator Insert(Iterator tWhere, const T& tWhat) // These two use iterators now
   {
       if (mSize == mCapacity)
           Reserve(2 * mCapacity);
       
       int tSize = 0;
       T* tData = new T[mCapacity];
       for (int i = 0; i < mSize; i++)
       {
           if(i == tWhere)
           {
               tData[tSize] = tWhat;
               tSize++;
           }
           tData[tSize] = mData[i];
           ++tSize;
       }
       
       delete[] mData;
       mData = tData;
       mSize = tSize;
       
       Iterator tAnswer(mMyVector, tWhere);
       return tAnswer;
   }
   Iterator Erase(Iterator tWhere)
   {
       int tSize = 0;
       T* tData = new T[mCapacity];
       for (int i = 0; i < mSize; i++)
       {
           if (i == tWhere)
           {
               ++tSize;
               tData[i] = mData[tSize];
           }
           tData[i] = mData[tSize];
           ++tSize;
       }
       delete[] mData;  
       mData = tData;  
       mSize = i;  
       Iterator tAnswer(mMyVector, tWhere+1);
       return tAnswer;
   }
   Iterator Begin()
   {
       Iterator tAnswer(mMyVector, 0);
       return tAnswer;
   }
   Iterator End()
   {
       Iterator tAnswer(mMyVector, mSize-1);
       return tAnswer;
   }
};
template<typename T>
T Vector<T>::sUndefined;
```
```C++
template <typename T>
class List
{
   struct ListNode
   {
       ListNode()
       {
           mPrev = nullptr;
           mNext = nullptr;
       }
       T mData;
       ListNode* mPrev;
       ListNode* mNext;
   };
   ListNode* mHead;
   ListNode* mTail;
public:
   List()
   {
       //mHead = nullptr;// Technically works, but we gain so much with sentinel nodes
       //mTail = nullptr;
       mHead = new ListNode;// You always know there is a node to the left and right
       mTail = new ListNode;
       mHead->mNext = mTail;
       mTail->mPrev = mHead;
   }
   List(const List& tOther) : List();
   
   List& operator = (const List& tRHS);
   ~List();
   void PushFront(const T& tWhat);
   
   void PopFront();
   
   static T sUnspecifiedStaticVar;
   T& Front();
   void PushBack(const T& tWhat);
   void PopBack();
   T& Back();
   int Size();
   void Clear();
   T& At(int tWhere) const;
   class Iterator
   {
       ListNode* mCurrent;
       friend class List<T>;
       Iterator(ListNode* tStart)
       {
           mCurrent = tStart;
       }
   public:
       T& GetData()
       {
           return mCurrent->mData;
       }
       void Next()
       {
           mCurrent = mCurrent->mNext;
       }
       bool IsEqual(const Iterator& rhs) const
       {
           return mCurrent == rhs.mCurrent;
       }
   };
   Iterator Insert(Iterator tWhere, const T& tWhat)
   {
       ListNode* tNew = new ListNode;
       ListNode* tPrev = tWhere->mPrev;
       ListNode* tNext = tWhere->mNext;
       tNew->mData = tWhat;
       tPrev->mNext = tNew;
       tNew->mPrev = tPrev;
       tNew->mNext = tNext;
       tNext->mPrev = tNew;
       return Iterator(tNew);
   }
   Iterator Erase(Iterator tWhat)
   {
       ListNode* tPrev = tWhat->mPrev;
       ListNode* tNext = tWhat->mNext;
       delete tWhat;
       tPrev->mNext = tNext;
       tNext->mPrev = tPrev;
       return Iterator(tNext);
   }
   Iterator Begin()
   {
       return Iterator(mHead->mNext);
   }
   Iterator End()
   {
       return Iterator(mTail);
   }
};
```
### 補足情報(FW/ツールのバージョンなど)
Visual Studio 2019 ver.16.0.2.
  • C++

    8570 questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る