6

次のコードでは、main関数はテンプレート関数の代わりに通常の関数を使用しています。

#include <iostream>

using namespace std;

template <class T>
void num(T t){cout<<"T : "<<t;}

void num(int a){cout<<"wT : "<<a;}


int main()
{
    num(5);
    return 0;
}

この背後にある考えられる理由は何ですか?

4

2 に答える 2

8

ハーブサッターの優れた記事「関数テンプレートを専門にしないのはなぜですか?」をご覧ください。

引用するには:

「最後に、関数テンプレートのみに焦点を当て、オーバーロードルールを検討して、さまざまな状況で呼び出されるルールを確認しましょう。ルールは、少なくとも高レベルでは非常に単純であり、古典的な2クラスシステムとして表現できます。

  1. 非テンプレート関数は第一級市民です。パラメータタイプおよび任意の関数テンプレートに一致する単純な古い非テンプレート関数が、他の点では適切な関数テンプレートよりも選択されます。

  2. 少なくとも同じくらい良い一級市民がいない場合は、次に二級市民と同じように機能ベースのテンプレートを参照します。どの関数ベーステンプレートが選択されるかは、どれが最もよく一致し、「最も専門的」であるかによって異なります(重要な注意:この「専門的」の使用は、奇妙なことに、テンプレートの専門化とは関係ありません。不幸な口語表現です)。難解なルール:

    • 「最も特殊な」関数ベーステンプレートが1つあることが明らかな場合は、そのテンプレートが使用されます。そのベーステンプレートが使用されているタイプに特殊化されている場合は、特殊化が使用されます。それ以外の場合は、正しいタイプでインスタンス化されたベーステンプレートが使用されます。

    • それ以外の場合、「最も特殊な」関数ベーステンプレートが同点の場合、コンパイラはどちらがより適切かを判断できないため、呼び出しはあいまいになります。プログラマーは、呼び出しを修飾し、どれが必要かを言うために何かをしなければなりません。

    • そうでなければ、一致させることができる関数ベースのテンプレートがない場合、呼び出しは正しくなく、プログラマーはコードを修正する必要があります。」

コード例では、David Z.が指摘しているvoid num(int a)ように、最初のルールで一致するため、非テンプレート関数が選択されます。追加の関数テンプレートは、それらがより適切に一致する場合にのみ考慮されます

于 2012-04-24T09:27:20.777 に答える
5

この場合にテンプレートメソッドを呼び出すには、のnum<int>(5)代わりに明示的にメソッドを呼び出す必要がありますnum(5)。コンパイラーは推測できますが、ジェネリック方式よりも非ジェネリック方式の方が適しています。この動作はhttp://ideone.com/ccDJPで確認できます。

于 2012-04-24T03:38:44.587 に答える