2016-07-09 4 views
0

私が作業しているプロジェクトでは、データ構造をカプセル化するC++ライブラリを作成しました。各データ構造に対して、私はエレガントにデータをナビゲートするカスタムイテレータを作成しました。私はこのビルドエラーが発生したときに、これらのクラスでテンプレートの特殊化を試みるまで、すべてうまくいった: エラー:不完全な型の無効な使用。C++テンプレートの特殊化友人イテレータエラー:不完全な型の無効な使用

は、私は、全体の問題を簡素化

...これで一週間以上のための私の頭を打ちましたし、ネット上で役立つ、何も見つからなかったので、私はあなたのいくつかはこれで私を助けることができるかもしれないと思ってきました:

template<typename T> 
class DataStructureIterator; 
// OK 
template<typename T> 
class DataStructure { 
    friend class DataStructureIterator<T>; 
    public: 
     typedef DataStructureIterator<T> iterator; 

     ... 

     iterator begin() { 
      return iterator(this); 
     } 

     iterator end(){ 
      return iterator(count); 
     } 

}; 
// ERROR: "Invalid use of incomplete type" (on ANY specialization attempt) 
template<> 
class DataStructure<double> { 
    friend class DataStructureIterator<double>; 
    public: 
     typedef DataStructureIterator<double> iterator; 

     ... 

     iterator begin() { 
      return iterator(this); 
     } 

     iterator end(){ 
      return iterator(count); 
     } 

}; 

template<typename T> 
class DataStructureIterator { ... } 

例:

template<typename T> 
struct DoublyLinkedListEntry { 
    T value; 
    DoublyLinkedListEntry* next; 
    DoublyLinkedListEntry* previous; 
}; 

template<typename T> 
class DoublyLinkedListIterator; 

template<typename T> 
class DoublyLinkedList { 
    friend class DoublyLinkedListIterator<T>; 
    public: 
     typedef DoublyLinkedListIterator<T> iterator; 

     DoublyLinkedList() { 
      head = nullptr; 
      tail = nullptr; 
      count = 0; 
     } 

     ~DoublyLinkedList() { 
      empty(); 
     } 

     void add(const T& value) { 
      DoublyLinkedListEntry<T>* element = new DoublyLinkedListEntry<T>; 
      element->value = value; 
      element->next = nullptr; 
      element->previous = tail; 
      if(head==nullptr) { 
       head = element; 
      } else { 
       tail->next = element; 
      } 
      tail = element; 
      ++ count; 
     } 

     iterator begin() { 
      return iterator(this); 
     } 

     iterator end(){ 
      return iterator(count); 
     } 
    private: 
     void empty(){ 
      DoublyLinkedListEntry<T>* temp = head; 
      DoublyLinkedListEntry<T>* del = temp; 
      while(del != nullptr) { 
       temp = temp->next; 
       delete del; 
       del = temp; 
      } 
     } 

     DoublyLinkedListEntry<T>* head; 
     DoublyLinkedListEntry<T>* tail; 
     std::size_t count; 
}; 

template<> 
class DoublyLinkedList<double> { 
    friend class DoublyLinkedListIterator<double>; 
    public: 
     typedef DoublyLinkedListIterator<double> iterator; 

     DoublyLinkedList() { 
      head = nullptr; 
      tail = nullptr; 
      count = 0; 
     } 

     ~DoublyLinkedList() { 
      empty(); 
     } 

     void add(double& value) { 
      DoublyLinkedListEntry<double>* element = new DoublyLinkedListEntry<double>; 
      element->value = value; 
      element->next = nullptr; 
      element->previous = tail; 
      if(head==nullptr) { 
       head = element; 
      } else { 
       tail->next = element; 
      } 
      tail = element; 
      ++ count; 
     } 

     iterator begin() { 
      return iterator(this); 
     } 

     iterator end(){ 
      return iterator(count); 
     } 
    private: 
     void empty(){ 
      DoublyLinkedListEntry<double>* temp = head; 
      DoublyLinkedListEntry<double>* del = temp; 
      while(del != nullptr) { 
       temp = temp->next; 
       delete del; 
       del = temp; 
      } 
     } 

     DoublyLinkedListEntry<double>* head; 
     DoublyLinkedListEntry<double>* tail; 
     std::size_t count; 
}; 

template<typename T> 
class DoublyLinkedListIterator { 
    public: 
     DoublyLinkedListIterator(){ 
      list = nullptr; 
      current_item = nullptr; 
      offset = 0; 
     } 

     DoublyLinkedListIterator(DoublyLinkedList<T>* list){ 
      this->list = list; 
      current_item = list->head; 
      offset = 0; 
     } 

     DoublyLinkedListIterator(std::size_t total){ 
      list = nullptr; 
      current_item = nullptr; 
      offset = total; 
     } 

     ~DoublyLinkedListIterator(){} 

     const T operator*(){ 
      return current_item->value; 
     } 

     bool operator!=(const DoublyLinkedListIterator<T>& it) const { 
      return offset!=it.offset; 
     } 

     DoublyLinkedListIterator<T>& operator++(){ 
      if(current_item!=nullptr) { 
       current_item = current_item->next; 
      } 
      ++offset; 
      return *this; 
     } 

    private: 
     DoublyLinkedList<T>* list; 
     DoublyLinkedListEntry<T>* current_item; 
     std::size_t offset; 
}; 

ビルドエラー:

In file included from ../src/Learning.cpp:11:0: 
../src/DoublyLinkedList.h: In member function ‘DoublyLinkedList<double>::iterator DoublyLinkedList<double>::begin()’: 
../src/DoublyLinkedList.h:107:20: error: return type ‘DoublyLinkedList<double>::iterator {aka class DoublyLinkedListIterator<double>}’ is incomplete 
    iterator begin() { 
        ^
../src/DoublyLinkedList.h:108:24: error: invalid use of incomplete type ‘DoublyLinkedList<double>::iterator {aka class DoublyLinkedListIterator<double>}’ 
    return iterator(this); 
         ^
../src/DoublyLinkedList.h:22:7: error: declaration of ‘DoublyLinkedList<double>::iterator {aka class DoublyLinkedListIterator<double>}’ 
class DoublyLinkedListIterator; 
    ^
../src/DoublyLinkedList.h: In member function ‘DoublyLinkedList<double>::iterator DoublyLinkedList<double>::end()’: 
../src/DoublyLinkedList.h:111:17: error: return type ‘DoublyLinkedList<double>::iterator {aka class DoublyLinkedListIterator<double>}’ is incomplete 
    iterator end(){ 
       ^
../src/DoublyLinkedList.h:112:25: error: invalid use of incomplete type ‘DoublyLinkedList<double>::iterator {aka class DoublyLinkedListIterator<double>}’ 
    return iterator(count); 
         ^
../src/DoublyLinkedList.h:22:7: error: declaration of ‘DoublyLinkedList<double>::iterator {aka class DoublyLinkedListIterator<double>}’ 
class DoublyLinkedListIterator; 

答えて

1

エラーメッセージはかなり明確です。あなたは、次のいずれかの方法を使用してこの問題を解決することができます

iterator begin() { 
     return iterator(this); 
    } 

    iterator end(){ 
     return iterator(count); 
    } 

:あなたは、次のような機能で、クラスのインスタンスを作成しようとすると

class DoublyLinkedListIterator<double>は不完全な型です。

  1. template<> class DataStructure<double>の定義の前にtemplate<typename T> class DoublyLinkedListIteratorの定義を移動し

  2. 上記の関数をインラインで定義しないでください。それらを宣言するだけです。 template<typename T> class DoublyLinkedListIteratorの定義の後に定義します。

+0

オプション2を使用するとすべて正常に動作します。どうもありがとう! –

関連する問題