2017-07-27 23 views
0

C++でテンプレート化されたクラスを継承するクラスを宣言することは可能ですか?基本的には、宣言時に私のテンプレートクラスは常に別のクラスを継承するというヒントをコンパイラに伝えたいと思います。 は多分これが私のために問題である理由いくつかのコードが解消されます:継承リストを持つC++テンプレート宣言

template<typename T> 
class GrandparentClass 
{ 
public: 
    T grandparentMember; 
}; 

//this needs to be only a declaration, since I do not want classes of ParentClass with random T 
template<typename T> 
class ParentClass : public GrandparentClass<T> 
{ 

}; 

// this does not work: 
//template<typename T> 
//class ParentClass : public GrandparentClass<T>; 

// this does not either, because then the child class cannot access the variable from the grandparent class 
//template<typename T> 
//class ParentClass; 

template<> 
class ParentClass<int> : public GrandparentClass<int> 
{ 
public: 
    ParentClass() 
    { 
     grandparentMember = 5; 
    } 
}; 

template <typename T> 
class ChildClass : public ParentClass<T> 
{ 
public: 
    void foo() 
    { 
     std::cout << grandparentMember << "\n"; 
    } 
}; 

また、私はC++ 11

EDIT使用することはできません。

を私はこの簡単な方法を見つけました

template<typename T> 
class ParentClass : public GrandparentClass<T> 
{ 
public: 
    ParentClass() { ParentClass::CompilerError(); }; 
}; 

クラス内でCompilerError()メソッドを定義していないだけですべてが問題ありません。

+0

はい、動作するはずです。あなたはどこに問題が見えますか? –

+1

いいえ、クラス宣言は 'class foo;'から取ります。テンプレートであろうとなかろうと、ベースクラスを含むことはできません。そしてそれが可能であっても、専門化はまだそれを再び含める必要があります。 – StoryTeller

+0

問題は、定義を 'template class ParentClass:public GrandparentClass ;に変更できないことです。コード内でこれを編集します – lightxbulb

答えて

3

クラス宣言は、ポインタや参照などの値以外の変数宣言に本当に便利です。ただし、クラスメンバーにアクセスしたり、インスタンス化することはできません。宣言されたクラスが他のクラスから継承していることを知っていたとしても、必ずしもその情報をどのようにも利用できるとは限りません。

このように、コンパイラが完全な定義を学ぶとクラスが継承する内容を知ることは、コンパイラにとって重要なことです。コメントで明確化した後


:あなたには、いくつかの種類のクラステンプレートのインスタンス化を防ぎたい場合は、その定義は、それを行うための場所です。クラス本体の中のシンプルなstatic_assertがそのトリックを行います。 Boost.StaticAssertまたはそれ以前のSFINAEのトリックは、プレC++ 11コードの仕事をします。

+0

私がしたいことを達成するための回避策はありますか? – lightxbulb

+1

@lightxbulbとは何ですか? –

+0

私はそれを特化したものとは異なるタイプ名でParentClassのインスタンス化を禁止しますが、祖父母のメンバーは引き続き子クラスからアクセス可能でなければなりません。基本的には、特定のタイプのTに対して、ParentClassの定義を提供したくありません。 – lightxbulb

1

コンパイル時ではなく、リンク時のエラーを遅らせることができれば、parent.hのすべてのメンバー関数を宣言し、parent.cppの定義を提供し、あなたが望むクラス。

Parent.h

template<typename T> 
class ParentClass : public GrandparentClass<T> 
{ 
    ParentClass(); 
}; 

class ParentClass<int>; 
class ParentClass<long int>; // or whatever 

Parent.cpp

template <typename T> 
ParentClass::ParentClass() : grandparentMember(5) {} 
+0

私はあなたのソリューションに触発されましたが、私の経験からより読みやすいので、コンパイル時のエラーに変えました。 – lightxbulb

関連する問題