2011-02-04 11 views
3

は、以下のテンプレート定義を仮定(コードは無意味です):質問++テンプレート

template<class X, class Y> 
bool FooBar(const Y& val) { return sizeof(X) + 4; } 

私は、次の呼び出しのコードが合法であることがわかっています

float temp = 0.f; 
FooBar<int>(temp); 

あなたが見ることができるように、第2のタイプのパラメータYは省略することができます。コンパイラは、tempという引数の型を見て、Yの型を推論します。

何のルールやC++テンプレートの仕様では、これを可能に?私はそれを見てかなり驚いた。

答えて

5

これはテンプレート引数の控除です。 FooBarの値パラメーターの型としてXを使用し、それをテンプレート引数なしで呼び出した場合と同じです。 IBM's compiler siteに詳細がある文書があります。

1

これは「暗黙のテンプレートのインスタンス化」と呼ばれます。標準のセクション14.7.1を参照してください。これは関数テンプレートによく使用されることに注意してください。

+1

インスタンスです。 –

3

14.7.1項2:

関数テンプレートの特殊化は、明示的にインスタンス化または明示的に特化されている場合を除き、専門はに関数定義を必要と文脈の中で参照されている場合、関数テンプレートの特殊化が暗黙的にインスタンス化されます存在する。

エレミヤが指摘するように、引数の控除は、あなたが本当には約求めているものです:

14.8.2:

テンプレート関数の特殊化が参照されると、テンプレートのすべて引数には値が必要です。値は明示的に指定することも、場合によっては使用から推定することもできます。 ...

プロセスがそこに詳細に記載されています。

出典:ISO/IEC 14882:1998(E)

+1

これは、テンプレートの引数がわかっている場合に起こります。引数の取得は、テンプレート引数の控除によって行われます。 –

+0

あなたが正しいです、セクション14.8.2は具体的に控除プロセスについて説明します。 –

1

あなたは、必ずしも各タイプのパラメータを指定する必要はありません。基本的に、コンパイラは渡されたパラメータの型からYを取り出し、宣言でXを指定しました。 JavaとC++のもう一つの違い。コンパイラは、それが呼び出しに使用するテンプレート引数を取得していないか、しかし、実行するための関数本体のコピーを生成する際