関数テンプレートの構文
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
言語に導入されたので(テンプレート内のいくつかの宣言を明確にするために別のキーワードを追加する必要があることに気づいたとき); 次に、引数の宣言についても「後付け」されました。このキーワードの使用法は、その間に書かれたプログラム/ドキュメントとの互換性のために保持されました。template
class
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