テンプレートクラスとクラステンプレートの違いは何ですか?
回答:
これは多くの人にとってよくある混乱のポイントです(ウィキペディアのジェネリックプログラミングページ、いくつかのC ++チュートリアル、およびこのページの他の回答を含む)。C ++に関する限り、「テンプレートクラス」のようなものはなく、「クラステンプレート」だけがあります。 そのフレーズの読み方は、「関数のテンプレート」である「関数テンプレート」とは対照的に、「クラスのテンプレート」です。 繰り返しますが、クラスはテンプレートを定義せず、テンプレートはクラス(および関数)を定義します。たとえば、これはテンプレート、具体的にはクラステンプレートですが、クラスではありません。
template<typename T> class MyClassTemplate
{
...
};
宣言MyClassTemplate<int> は、クラス、または基本的にはテンプレートに基づくクラスです。 テンプレートに基づくクラスとテンプレートに基づかないクラスの特別なプロパティはありません。 特別なプロパティはテンプレート自体のものです。
「テンプレートクラス」という句は、C ++に関する限り、「テンプレート」という単語を名詞「クラス」に適用した場合、形容詞としての意味を持たないため、何の意味もありません。これは、の存在を意味クラスである(または定義)テンプレートC ++に存在する概念ではありません。
単語が実際の言語で「テンプレートクラス」の順序で表示されるという事実に基づいている可能性があるため、よくある混乱を理解しています。これはまったく別の話です。
違いは、「テンプレートクラス」という用語がC ++標準に存在しないことです。これは主に、「クラステンプレート」という用語が紛らわしいと考える人々によって使用される用語です(Qt企業のNokiaや以前のTrolltechなど)。
標準にはその概念がないので、違いを生むのは他の人々次第です。同義語として使用する人もいれば、「テンプレートクラス」という用語は、インスタンス化された、または明示的に特殊化されたクラステンプレートを指し、「クラステンプレートの特殊化」という用語と同等になると言う人もいます。歴史的に、それはこの意味を持っていました。注釈付きのリファレンスマニュアルのページ343で定義
クラステンプレートから生成されたクラスは、名前としてtemplate-class-nameを使用して特別に定義されたクラスと同様に、テンプレートクラスと呼ばれます。
非終端テンプレートクラス名は非末端に相当し、テンプレート-ID今日の標準で使用してダウンしていますtemplate-name < arguments >。
疑わしい古い用語を使用するよりも重要な今日の用語に慣れるため
// (1) defines a class template
template<typename T> class A { };
// (2) defines a class template explicit specialization
template<> class A<int> { };
// (3) defines a class template partial specialization
template<typename T> class A<T*> { };
// (4) explicitly instantiates A<char>.
template class A<char>;
// (5) implicitly instantiates A<short> (because of the member declaration)
struct D { A<short> a; };
テンプレートクラスはテンプレートメソッドのデザインパターンに関連していますが、クラステンプレートは単なる「穴埋め」クラステンプレートです。
クラステンプレートは、さまざまなタイプのオブジェクトの汎用クラスです。基本的には、パラメータに基づいてクラスを生成するための仕様を提供します。新しいオブジェクトが作成されるたびに、その目的のために新しいクラスがメモリ内で実行されます。これはクラステンプレートのインスタンス化と呼ばれ、クラスのインスタンス化された各バージョンはテンプレートクラスと呼ばれます。
この論文を見てください(wg21から、1992年に発行されました):
一貫した用語
これまでの議論と意見の相違の多くは、テンプレートを説明する章で使用されている用語に関するものでした。最も頻繁に行われているのは、さまざまなアイデアや意図を表現するための「function-template」と「template-function」のさまざまなアプリケーションです。一貫した命名が適用されていないため、結果は混乱と議論になります。
この文書の目的のために、テンプレートについての議論における委員会による正式な採用の提案として、そして文書を明確にする目的のために; 末尾の「-template」がテンプレートによって記述されたタイプまたは関数のセットを記述するという形式化を採用することを提案します。その先頭に「テンプレート- 」、の一部のテンプレート定義を説明するために使用される「-template」をなど、
'template-member-function'。したがって:-
- 'function-template':テンプレートによって記述された関数のセットで、そのテンプレートへの引数として提供されたいくつかの型情報にパラメトリックです。例えば :-
template<class T> int nullcheck( T* pT )
{ return ( pT != 0 ); }
- 'class-template':テンプレートによって記述されたクラスのセットであり、そのテンプレートへの引数として提供されるいくつかの型情報にパラメトリックです。例えば :-
template<class T> class S {
int i;
public:
int sep_member();
int imm_member()
{ return 2; }
}
- 'template-function':この用語は許可されなくなりました。**
'template-class':この用語は許可されていません。**
'member-function-template':この用語は、テンプレート定義で現在サポートされていないプロパティを表すため、許可されていません。上記の用語規則を使用すると、これは、定義自体がテンプレートである非クラステンプレートのメンバーを記述します。例えば :-
class Normal { public:
template<class T> int foo(T*pT)
{ return ( pT == 0 ); }
};
ただし、テンプレートは現在グローバルスコープに制限されているため、このようなテンプレートは無効です。
- 'template-static-member-function':
- 'テンプレート-メンバー-関数':
- 'template-static-member':
- 'template-static-data-member ' template-member ': メンバーが属する' class-template 'とは別に表示されるメンバーの定義の代替用語。例えば :-
template<class T> int S<T>::sep_member()
{ return i; }
Normalあなたが上で説明したクラスについて:私はそのようなmember-function-templateが禁止されていることに気づいていませんでした。私が試したすべてのコンパイラで受け入れられます。何が足りないのですか?