2012-04-22 15 views
4

構文なぜC++テンプレートパラメータをクラス型として宣言する必要がありますか?関数テンプレートの

template <**class** T, ...> 
    returntype functionname(arguments) 
    { 
      ..... 
      ..... 
    } 

私は2つの質問がありますか? (classキーワードを使用したすなわち )テンプレートパラメータは、クラス型として宣言されなければならないのはなぜ

  1. 我々は、コンパイラ が何をするかの事その後、クラス型としてそれを宣言?
+2

標準がそうだから –

+2

@VJovic:ナンセンス。標準では、 "テンプレートパラメータはクラス型として宣言する必要がありますが、" class' ***キーワードで宣言する必要があります***。また、「標準がそう言っているので」という言葉は、標準化の間になされた選択の背後にある論理的根拠を理解するために全く役に立たない。 –

答えて

1

標準によれば、classtypenameの2つのキーワードがあります。それらのいずれかをテンプレート定義に使用できます。どちらも同じ意味です:class(またはtypename)をテンプレート定義に書き込むと、テンプレートのユーザーはタイプをテンプレート引数として渡す必要があります。それ以上のことは意味しません。それが関数テンプレートである場合、テンプレート引数は、関数への引数から(場合によっては)と推定される場合があります。

11

これは、template引数のclassの使用に起因する通常の混乱です。

そのclassはクラスとは関係ありません。それは、テンプレートだけでなくタイプクラステンプレート引数(テンプレート引数)を受け入れることを意味し、任意のタイプであり、クラスではありません。

なぜ、彼らはclassを選んだのですか?彼らはC++プログラムでは必ず使用されていなかったキーワードを使用しなければならなかったので、それはC++の予約済みキーワードであるため、classはokでした。

classの代わりにtypenameというキーワードがあります。彼らは完全に同等ですしかし、私の意見ではtypenameという名前は、「次のものは型引数です」と言うだけで、クラスでなければならないと思うので、はっきりしています。

なぜ両方の構文が許可されるのですか? typenameキーワードは、の後にという言語で導入されていたため(テンプレート内でいくつかの宣言を明確にするために別のキーワードを追加する必要があることに気付いたとき)。引数の宣言の場合には "改装されました"。 classキーワードのこの使用法は、その間に書かれたプログラム/文書との互換性のために保持されていました。ここ


  1. 私は明らかに、私は一般的な(C++ 11、14.1¶4)における非型テンプレートパラメータを意味し、簡単にするために "不可欠" と言います。
  2. テンプレートパラメータにclassとtypenameの意味に違いはありません。

    (C++ 11、§14。1¶2)

+0

「いくつかのコーナーケース」?私は 'typedef typename TemplateParamClass :: nestedClass ShortName'というよりも頻繁に書く必要があります。 – leftaroundabout

+0

@leftaroundについて:あなたは正しいですが、それはコーナーケースが実際には多すぎると言っていますが、テンプレートを学ぶとすぐに立ち上がる問題ではありません。それでも、私はフレーズを少し変えました。 –

0

(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 
2

これは、言語で定義されているためです。この文脈における「クラスT」は、「Tはある種の名前です」を意味し、「Tはいくつかのクラスの名前ではありません」を意味します。

私は、別の予約語を追加したくないという願望に根拠があると信じています。

しかし、この言語では最終的に別の予約語が追加されました。「typename T」と同じことが言えます。あなたは、templateにクラスだけでなく、標準型を渡すことができ

1

注:だから

template <class T, int N> class mysequence {..}; 

は、ここclassキーワードは、クラスとしてTを扱うようにコンパイラに指示します。そして、Nは整数として扱われます。

+0

まあ、**特定の**標準タイプ。 –

関連する問題