テンプレートクラスとクラステンプレートの違いは何ですか?


85

テンプレートクラスとクラステンプレートの違いは何ですか?

回答:


125

これは多くの人にとってよくある混乱のポイントです(ウィキペディアのジェネリックプログラミングページ、いくつかのC ++チュートリアル、およびこのページの他の回答を含む)。C ++に関する限り、「テンプレートクラス」のようなものはなく、「クラステンプレート」だけがあります。 そのフレーズの読み方は、「関数のテンプレート」である「関数テンプレート」とは対照的に、「クラスのテンプレート」です。 繰り返しますが、クラスはテンプレートを定義せず、テンプレートはクラス(および関数)を定義します。たとえば、これはテンプレート、具体的にはクラステンプレートですが、クラスではありません

template<typename T> class MyClassTemplate
{ 
    ...
};

宣言MyClassTemplate<int> は、クラス、または基本的にはテンプレートに基づくクラスです。 テンプレートに基づくクラスとテンプレートに基づかないクラスの特別なプロパティはありません。 特別なプロパティはテンプレート自体のものです。

「テンプレートクラス」という句は、C ++に関する限り、「テンプレート」という単語を名詞「クラス」に適用した場合、形容詞としての意味を持たないため、何の意味もありません。これは、の存在を意味クラスである(または定義)テンプレートC ++に存在する概念ではありません。

単語が実際の言語で「テンプレートクラス」の順序で表示されるという事実に基づいている可能性があるため、よくある混乱を理解しています。これはまったく別の話です。


+1。クラスの「起源」を区別することが何らかの理由で役立つ場合があります。その場合、「テンプレートクラス」という用語を合理的に使用できますが、与えた理由から、これが何を意味するかを慎重に定義することをお勧めします。 。
j_random_hacker 2009年

1
@j_random_hacker -以下litbの答えを見ますが、要するに、に対する優先語は、「クラステンプレートの特殊化」である
わからない

@わからない:実際には、「クラステンプレートの特殊化」は、テンプレートの明示的または部分的な特殊化を定義するプロセスを参照することもできるため、少しあいまいです。実際の「クラス」を生成するために必要ではありません。:)IMHOの「クラステンプレートのインスタンス化」は最も明確な用語です。
j_random_hacker 2009年

2
@j_random_hacker:それには適切な用語があります-「明示的なクラステンプレートの特殊化」と「部分的な明示的なクラステンプレートの特殊化」。面倒ですが、あいまいで
はありません

1
-1用語は、その用語を使用する人々にとっての意味を意味します。文字通りの意味を分析し始めることは無意味です。日常生活や工学の他の用語で試してみてください。要約すると、この答えはたわごとです。ビャーネを引用したSHHの答えは大丈夫です。
乾杯とhth。-アルフ

13

C ++の作成者であるBjarneStroustrupは、彼の著書「C ++プログラミング言語第4版、23.2.1テンプレートの定義」で次のように述べています。

クラステンプレートテンプレートクラスという用語を意味的に区別する人がいます。私はしません。それは微妙すぎるでしょう:それらの用語は交換可能であると考えてください。同様に、関数テンプレートテンプレート関数と互換性があると考えています


12

違いは、「テンプレートクラス」という用語が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; };
  • ARMはクラス(2)を呼び出し、(4)と(5)によって生成されたクラスをテンプレートクラスと呼びました。ARMが部分的な特殊化についてすでに知っていたかどうかはわかりません。ただし、その場合、(3)はクラスを定義せず、テンプレートを定義するため、(3)はテンプレートクラスとは呼ばれませんでした。
  • 現在の標準はクラス(2)を呼び出し、(4)および(5)クラステンプレートの特殊化によって生成されたものを呼び出します。また、(3)は、明示的な特殊化とは対照的に部分的な特殊化と呼ばれます。また、(3)スペシャライゼーション(3.2 / 5-ただしクロスリンクを明確にする)と呼ばれることもありますが、「スペシャライゼーション」を「クラス、関数、またはクラス」として定義しているため、これは完全には明確ではありません。 (3)が満たさないメンバー」。

3
ふふ。ええと他のいくつかもまだそのセットに貢献しています。特に、C ++ FaqliteとQtドキュメント。よくある質問の作成者はメールで、「スペシャライゼーション」という単語を使用すると混乱が少なくなるため、「スペシャライゼーション」という単語を使用する方がよいことを説明する別のFAQ項目を入れたいと言っていました(ユーザーが作成したスペシャライゼーションの種類に「明示的なスペシャライゼーション」を使用します。その後)。Qtの連中は、「クラステンプレート」という用語を使いたくないと言っていました。彼らはそれがあまりにも「不自然」だと感じています。残念な。
Johannes Schaub-litb 2009年

@ JohannesSchaub-litb:ARMは、およそ1991年のIIRCであるBjarneStroustrupとMargaretEllisによって作成されました。ARMからの引用は、BjarneのTCPPL第4版からのSHHの引用と矛盾します。したがって、古い(標準以前の)用語と現在の用語を区別するのは良いことです。
乾杯とhth。-アルフ


1

クラステンプレートは、クラスを生成するために使用されるテンプレートですが、テンプレートクラスは、テンプレートによって生成されるクラスです。


0

テンプレートクラス:一般的な定義を持つクラス、または情報がクライアントから提供されるまでインスタンス化されないパラメーターを持つクラス。プレーンテンプレートの専門用語と呼ばれます。プレフィックステンプレートを使用してTを使用するだけのクラスです。クラステンプレート:クラスの個々の構成は、クラステンプレートによって指定されます。これは、クラスを使用して個々のオブジェクトを構成する方法とほぼ同じです。テンプレートクラスのオブジェクトを参照しますEx-classnameobjectname(argument list)


0

クラステンプレートは、さまざまなタイプのオブジェクトの汎用クラスです。基本的には、パラメータに基づいてクラスを生成するための仕様を提供します。新しいオブジェクトが作成されるたびに、その目的のために新しいクラスがメモリ内で実行されます。これはクラステンプレートのインスタンス化と呼ばれ、クラスのインスタンス化された各バージョンはテンプレートクラスと呼ばれます。


0

この論文を見てください(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が禁止されていることに気づいていませんでした。私が試したすべてのコンパイラで受け入れられます。何が足りないのですか?
dan_din_pantelimon
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.