2016-06-17 13 views
0

私はSOのように循環するC++テンプレートの質問の帯があります知っている:しかし、私は現在、うんざりするg++エラーに対して戦ってるC++テンプレートのエラー質問

は:

In file included from LinkedList.cpp:1:0:                                 
LinkedList.h:9:7: error: partial specialization 'class List<T>' does not specialize any template arguments                
class List<T>;                                       
    ^                                        
LinkedList.h:15:51: error: expected class-name before '{' token                           
template <class T> class LinkedList : public List {                              
               ^                             
In file included from main.cpp:2:0:                                  
LinkedList.h:9:7: error: partial specialization 'class List<T>' does not specialize any template arguments                
class List<T>;                                       
    ^                                        
LinkedList.h:15:51: error: expected class-name before '{' token                           
template <class T> class LinkedList : public List { 

私のプログラムは(fまたは簡潔さのために) "インターフェース" List.hとリンクされたリストのためのヘッダ - インプリメンテーションファイルコンボを含む3つのファイル。コンパイルエラーが示すように、ListインターフェイスをLinkedList.hに拡張すると問題が発生します。私は本当になぜこれらが起こっているのか分からない。

template <class T> 
friend class List<T>; 

template<class T> 
class List<T>; 

とやって:私はのようなものの組み合わせを使用することによって、問題を解決しようとした

#include "List.h" 

をここで両方LinkedList.cppLinkedList.h

List.h

#ifndef __A2_LIST_H__ 
#define __A2_LIST_H__ 

/** 
* A simple interface for creating new List classes. 
* This was chosen to reduce coupling between objects. 
*/ 
template <typename T> class List { 

public: 
     virtual bool add(T data) = 0; 
     virtual void add(unsigned index, T data) = 0; 
     virtual void clear() = 0; 
     virtual bool contains(T data) = 0; 
     virtual T get(unsigned index) = 0; 
     virtual unsigned indexOf(T data) = 0; 
     virtual unsigned lastIndexOf(T data) = 0; 
     virtual bool remove(T data) = 0; 
     virtual T set(unsigned index, T data) = 0; 
     virtual unsigned int size() = 0; 
     virtual bool isEmpty() = 0; 

}; 

#endif // __A2_LIST_H__ 

ですここにはLinkedList.h

#ifndef __A2_LINKEDLIST_H__ 
#define __A2_LINKEDLIST_H__ 

#include <cstddef> 

#include "List.h" 

template <class T> 
class List<T>; 

#if !defined(nullptr) 
#define nullptr NULL 
#endif 

template <class T> class LinkedList : public List { 

public: 
    LinkedList(unsigned capacity); 

    virtual bool add(T data); 
    virtual void add(unsigned index, T data); 
    virtual void clear(); 
    virtual bool contains(T data); 
    virtual T get(unsigned index); 
    virtual unsigned indexOf(T data); 
    virtual unsigned lastIndexOf(T data); 
    virtual bool remove(T data); 
    virtual T set(unsigned index, T data); 
    virtual unsigned int size(); 
    virtual bool isEmpty(); 

    void addFirst(T data); 
    void addLast(T data); 
    unsigned find(T data); 

protected: 
    class Node { 
     public: 
      Node(T data) { 
       this->data = data; 
      } 

      T data; 
      Node *next, *previous; 
    }; 

    Node *head, *tail; 

private: 
    unsigned capacity, _size; 

    LinkedList::Node* _seek(unsigned index); 

}; 

#endif // __A2_LINKEDLIST_H__ 

、ここでは、この背後にある思考プロセスは私が先に自分のアプリケーションを開発する上の電荷として疎結合を維持したいものですLinkedList.cpp

#include "LinkedList.h" 

template <class T> LinkedList<T>::LinkedList(unsigned capacity) { 
    this->capacity = capacity; 
    this->_size = 0; 
} 

template <class T> bool LinkedList<T>::add(T data) { 
    this->addFirst(data); 
    return true; 
} 

template <class T> void LinkedList<T>::add(unsigned index, T data) { 
    if(index > this->capacity) { 
     throw "Index cannot be greater than the capacity"; 
    } 

    static LinkedList<T>::Node *node = new LinkedList::Node(data); 

    if(index == 0 && this->_size == 0) { // adding to empty list 
     this->addFirst(data); 
    } else if(index == this->_size + 1) { // end of list 
     this->addLast(data); 
    } else { // somewhere in the middle 
     LinkedList<T>::Node *fNode = this->_seek(data); 
     if(fNode != NULL) { 
      // TODO: insert new node here 
     } 
    } 

    this->_size++; 
} 

template <class T> bool LinkedList<T>::isEmpty() { 
    return this->_size == 0; 
} 

template <class T> unsigned LinkedList<T>::size() { 
    return this->_size; 
} 

です。この問題を解決する方法とそれがなぜ発生するのかに関するアドバイスは非常に高く評価されます。私はまだC++の新機能ですので、これらの問題の多くはそれほど意外ではないです。

答えて

1

をする必要がありますtemplate <class T> class LinkedList : public List {を信じて、試してみてください。

template <class T> class LinkedList : public List<T> { /*...*/ }; 

List<T>だけではなくList注意してください)完全なクラス宣言を含めるので、LinkedList.hの前方宣言されたtemplate <class T> class List部分の必要はありません。

注目すべきもう一つのことは、テンプレートクラスの実装が、別のLinkedList.cppファイルではなく、ヘッダーファイル内にあることです。 C++はテンプレート定義のバイナリを保存することはできず、ヘッダにインクルードすることによってコンパイル時に派生させる必要があります。ヘッダーに非テンプレート(および非インライン)関数の実装を定義するのとは異なり、それらが一度だけ定義されることを保証するのに十分な意味があります。

+0

それでした!先端のおかげで、それは私のエラーの残りの部分を押しつぶした。私はそれを将来のために心に留めておきます! – djthoms

0

は、私はあなたがそれを専門にしていないので、template <class T> List<T>にあなたは、リストの末尾から<T>を削除するべきであると信じている、と私はあなたのLinkedListの定義ではtemplate <class T> class LinkedList : public List<T> {