2016-07-21 2 views
-2

は、私は次のコードがあるとします。テンプレートの型名の再利用のメンバ変数で宣言されたときに

template<typename T> 
struct Task 
{ 
    T* item; 
    Task* next; 
    int priority; 
}; 

class PriorityQueue 
{ 
    public: 
     PriorityQueue(); 
     Enqueue(T* item, int priority); 
     T* Dequeue(); 

    private: 
     Task<T>* head; 

}; 

上記のコードはTが優先度つきキュークラスに宣言されていないコンパイルエラーがスローされます。タスク構造体のテンプレートクラスとして定義されているT *項目を参照したいのであれば、それを行うための正しい構文は何でしょうか?

おかげ

答えて

1

Tは特別な意味を持っていません。各テンプレートクラスまたはテンプレートメソッドは、template<typename T>またはその変形を使用してテンプレートとして宣言する必要があります。この場合、2つのTは自動的に同じになりません。

テンプレートクラスを使用する場合は、テンプレート引数の内容を指定する必要があります。構文はclassname<SomeType>です。 @Antonio Garridoが指摘するように。それはTaskは、インタフェースの一部ではないと思われるよう可能性があなたの頭のメンバーは今Task<T>* head;

として宣言されなければならないことを意味し、あなたのケースで、あなたはまた、優先度つきキュークラスの一部としてそれを宣言することができます。その方法T

template<typename T> 
class PriorityQueue 
{  
    struct Task 
    { 
    T* item; 
    Task* next; 
    int priority; 
    } 

    public: 
    PriorityQueue(); 
    Enqueue(T* item, int priority); 
    T* Dequeue(); 

    private: 
    Task* head; 
}; 

あなたは、テンプレートクラスを使用します。

PriorotyQueue<int> que; 
auto que = PriorotyQueue<int>(); // alternatively 
que.Engueue(3); 
+0

私の最初の実装では、PriorityQueueクラスはTask構造体で定義したTテンプレートを見つけることができないようです。どうすればいい? @Mantracker。 – Mantracker

+0

2番目のバージョン..(?!)を使用することによって私は従わない。 –

+0

混乱して申し訳ありませんが、私ははっきりと質問を編集しました – Mantracker

0

最後の行はところで

Task<T>* head; 

で、あなたが追加する必要があります ';'構造体/クラス定義を終了する

+0

修正をありがとう、私はコードを修正しました – Mantracker

1

あなたがTという名前の何かにリンクしていない限り、その方法1はうまくいきません。また、クラス宣言の後に;が必要です。

2つのTの値が同じかどうかは、同じではありません。テンプレートの全体のポイントは、「ちょっと」同じであるが異なるタイプの2つのタイプを持つことができるということです。彼らは同じインターフェイスを持っている点で唯一同じです。

私は1つのプログラムでは、このような何かを行うことができます:

PriorityQueue<std::string> stringQueue; 

PriorityQueue<int> intQueue; 

と私はキューの二つの異なる種類を持っているでしょう。 stringQueueはタイプPriorityQueue<std::string>であり、intQueueはタイプPriorityQueue<int>です。 C++コンパイラは2つの異なるバイナリをそれぞれコンパイルするため、これらは実際には同じインタフェースを共有する異なる型です。私のようなものでした場合:

intQueue.enqueue(5, 0); 
stringQueue.enqueue("hello world", 1); 

PriorityQueue<std::string>::enqueueが新しいTaskを作るとき、それはintQueueと整数とのTask<std::stringと同じになるため、その後stringQueueは、タイプTask<string>の単一Taskが含まれます。

Tはただ普通である変数ですが、あなたはまた、次のようにテンプレートを行うことができます。

template<typename Type> 
template<typename A>  //these two are basically the same as T 
template<Task SpecialTask> //here SpecialTask would have to be a 
          //Task or a child of Task 
template<class C>   //C must be a class 
template<typename T, U, V> //here are three templates in one declaration 
template<PriorityQueue PQ, 
     Task T, 
     typename U>  //three of different "lineage" 

のでどのようにコンパイラが PriorityQueue<int>Task<int>属性を持つ必要があることを知っているのですか?テンプレート属性を持っていることに気づいたときや、テンプレートを新しくしたときに、まだそれがなければ Task<int>のバイナリをコンパイルしてコンパイルします。

関連する問題