関数テンプレートの構文
template <**class** T, ...>
returntype functionname(arguments)
{
.....
.....
}
質問が 2 つありますか?
- テンプレート パラメーターをクラス型として宣言する必要があるのはなぜですか? (つまり、class キーワードを使用して)
- それをクラス型として宣言したとき、コンパイラは何をするでしょうか?
関数テンプレートの構文
template <**class** T, ...>
returntype functionname(arguments)
{
.....
.....
}
質問が 2 つありますか?
classこれは、 intemplate引数の使用から生じる通常の混乱です。
それclassはクラスとは何の関係もありません。これは単に、クラスだけでなく、任意の型である可能性がある型テンプレート引数 (整数1テンプレート引数とは対照的に) をテンプレートが受け入れることを示しています。
では、なぜ彼らは を選んだのclassでしょうか? C++ プログラムでは確実に使用されておらず、多かれ少なかれ「良さそうな」キーワードを使用する必要があったため、C++ ではclass既に予約済みのキーワードだったので問題ありませんでした。
class:typenameキーワードに代わるものがあることに注意してください。それらは完全に同等です2ですがtypename、私の意見では、名前が単に「次は型引数です」と言っているだけなので、それがクラスである必要があると思わせることなく、はるかに明確です。
両方の構文が許可されているのはなぜですか? キーワードは後でtypename言語に導入されたので(テンプレート内のいくつかの宣言を明確にするために別のキーワードを追加する必要があることに気づいたとき); 次に、引数の宣言についても「後付け」されました。このキーワードの使用法は、その間に書かれたプログラム/ドキュメントとの互換性のために保持されました。templateclass
template-parameter の class と typename の間に意味上の違いはありません。
(C++11、§14.1 ¶2)
それは、言語定義が使用するように指示している単語だからです。このコンテキストでの「クラス T」は、「T は何らかのクラスの名前である」ではなく、「T は何らかのタイプの名前である」という意味です。
その論理的根拠は、これ以上予約語を追加したくないという願望にあると思います。
ただし、言語は最終的にさらに別の予約語を追加しました。「typename T」と同じように言うことができます。
標準によると、キーワードはclassとの 2 つtypenameです。これらのいずれかをテンプレート定義で使用できます。どちらも同じ意味です:テンプレート定義でclass(または) を記述する場合、テンプレートのユーザーはテンプレート引数として型をテンプレートに渡す必要があることを意味します。それ以上の意味はありません。関数テンプレートの場合、テンプレート引数は(場合によっては) 関数への引数から推定される場合があります。typename
templateクラスだけでなく、標準型を に渡すことができることに注意してください。
template <class T, int N> class mysequence {..};
したがって、classここのキーワードはコンパイラに T をクラスとして扱うように指示します。また、N は整数として扱われます。
(1) テンプレート パラメータをクラス型として宣言する必要があるのはなぜですか?
完全に真実ではありません。も使えtypenameます。:)さらに重要なことは、特定のタイプのオブジェクトをパラメーターとして
宣言することもできます。const例えば
template<int I> // <---- 'I' is not a class/typename
class A { ... };
...
A<3> obj;
(2) クラス型として宣言した場合、コンパイラは何をしますか?
実際にはあまりありません。
ただし、コンパイラは、そのオブジェクトを呼び出すときに、型が実際には型名であることを確認します。例えば
template<class T>
class A { ... }; // ok ... not much to check
...
A<int> obj1; // compiler checks if 'int' is a type ---> yes
A<3> obj2; // compiler checks if '3' is a type ---> no